我正在尝试提供最终项目的骨架,这是一个FP计算器。但是,我遇到了一些麻烦。如果我编译这段代码,我会得到。我不确定这是什么汇编,但我相信它的32位并使用MASM编译器。
这一点是从输入文件中读取一行,然后进行执行操作。但是,我只是在做定义部分,我的合作伙伴会想出实施这些操作。
如果我要注释掉main函数,减去“Only_Nums,Character_Error:和Invalid_Char:”程序将会编译。
你能帮我确定一下它为什么不能编译。我能想到的唯一合乎逻辑的事情是,引用的代码没有先定义,但是,它是。
谢谢!
编辑:用SI替换ESI
.MODEL Small
.386
.387
.STACK
.DATA
FileN DB "FILENAME.DAT",0
Buffer DB 255 DUP (?)
StrinLen DB 0
Num2FP DB 0
Base DB 10.0
FPNum DT 0.0
.CODE
;------------------------------code to search file and opening file------------------------------------------------------------------------------------------
;------------------------------code for setting up the file pointer to, initally the first line, but after the first, to the next------------------------------
;------------------------------I am going to use buffer as the placeholder for the string of the line------------------------------------------------------------
;------------------------------String Length------------------------------------------------------------------------------------------------
String_Length PROC FAR
PUSHAD
Next_Element: MOV AL, BYTE PTR [BP + 0 + SI]
INC SI
CMP AL, 0Dh
JNE Next_Element
MOV [BP+2], SI
POPAD
RET
String_Length ENDP
;----------------------------------------------------------------------------------------------------------------------------------------
;------------------------------Macro to detect if trig and log are functions------------------------------------------------------------
Detect_Func MACRO W, X, Y, Z
INC SI
MOV BL, BYTE PTR [BP + 8 + SI]
.IF (BL != W) && (BL != Y)
JMP Character_Error
.ENDIF
INC SI
MOV BL, BYTE PTR [BP + 8 + SI]
.IF (BL != W) && (BL != Z)
JMP Character_Error
.ENDIF
ENDM
;------------------------------Reading the string from the input file, directing what the program does------------------------------------------
;------------------------------Didn't initially write this as procedure, so it will need to be converted----------------------------------------
Token PROC FAR
ReadIn: MOV BL, BYTE PTR [BP + 8 + SI]
.IF (BL < '0' && BL > '9')
JB Check_Invalid
.ENDIF
SUB BL, 30h
MOVZX BX, BL
MOV [BP+6], BX
FILD WORD PTR [BP + 6]
FLD DWORD PTR [BP + 2]
FMUL DWORD PTR [BP + 4]
FADDP ST(1), ST
FBSTP [BP + 2]
INC SI
CMP [BP], SI
JB Only_Nums
JMP ReadIn
Check_Invalid:
FLD DWORD PTR [BP + 2]
.IF BL == 0DH
;------------------------------write to file, move file pointer to next line and jump to readin-------------------------------------------------
;------------------------------there should be some stopping condition in the event there aren't any more lines to calculate--------------------
.ELSEIF BL == ' '
INC SI
JMP ReadIn
.ELSEIF BL == '+'
CALL FP_Add
RET
.ELSEIF BL == '-'
CALL FP_Sub
RET
.ELSEIF BL == '*'
CALL FP_Mul
RET
.ELSEIF BL == '/'
CALL FP_Div
RET
.ELSEIF BL == '('
.ELSEIF BL == ')'
.ELSEIF BL == '^'
CALL FP_Power
RET
.ELSEIF BL == '.'
CALL FP_Dec
.ELSEIF (BL == 'E' || BL == 'e')
CALL FP_E
.ELSEIF (BL == 'C' || BL == 'c')
Detect_Func 'o', 's', 'O', 'S'
CALL FP_Cos
RET
.ELSEIF (BL == 'S' || BL == 's')
Detect_Func 'i', 'n', 'I', 'N'
CALL FP_Sin
RET
.ELSEIF (BL == 'T' || BL == 't')
Detect_Func 'a', 'n', 'A', 'N'
CALL FP_Tan
RET
.ELSEIF (BL == 'L' || BL == 'l')
Detect_Func 'o', 'g', 'O', 'G'
Detect_Func '1', '0', '1', '0'
CALL FP_Log
RET
.ELSEIF (BL == 'R' || BL == 'r')
;------------------------------display error if number follows...?------------------------------------------------------------------------------------------
.ELSE
JMP Invalid_Char
.ENDIF
RET
Token ENDP
FP_Add PROC FAR
CALL Token
RET
FP_Add ENDP
FP_Sub PROC FAR
CALL Token
RET
FP_Sub ENDP
FP_Mul PROC FAR
CALL Token
RET
FP_Mul ENDP
FP_Div PROC FAR
CALL Token
RET
FP_Div ENDP
FP_Power PROC FAR
CALL Token
RET
FP_Power ENDP
FP_Dec PROC FAR
CALL Token
RET
FP_Dec ENDP
FP_E PROC FAR
CALL Token
RET
FP_E ENDP
FP_Cos PROC FAR
CALL Token
RET
FP_Cos ENDP
FP_Sin PROC FAR
CALL Token
RET
FP_Sin ENDP
FP_Tan PROC FAR
CALL Token
RET
FP_Tan ENDP
FP_Log PROC FAR
CALL Token
RET
FP_Log ENDP
MAIN PROC FAR
.STARTUP
MOV SI, 0
PUSH OFFSET StrinLen ;[BP+2]
PUSH OFFSET Buffer ;[BP]
MOV BP, SP
CALL String_Length
ADD SP, 4
POP BP
PUSH BP
PUSH OFFSET Buffer ;[BP+8]
PUSH OFFSET Num2FP ;[BP+6]
PUSH OFFSET BASE ;[BP+4]
PUSH OFFSET FPNum ;[BP+2]
PUSH OFFSET StrinLen ;[BP]
MOV BP, SP
CALL Token
ADD SP, 10
POP SP
Only_Nums: ;No operands was given error message
Character_Error: ;output error message (trig and log function)
Invalid_Char: ;output invalid character detected (invalid characted detected in input file
MAIN ENDP
END
答案 0 :(得分:2)
被拒绝的符号位于内部过程(PROC..ENDP)中,因此本地位于较新的MASM中。他们在手术之外是未知的。
如果您将冒号加倍(::
),则将该标签声明为“全局”:
Token PROC FAR
...
JB Only_Nums
...
JMP Character_Error
...
JMP Invalid_Char
...
RET
Token ENDP
MAIN PROC FAR
...
Only_Nums:: ;No operands was given error message
Character_Error:: ;output error message (trig and log function)
Invalid_Char:: ;output invalid character detected (invalid characted detected in input file
...
MAIN ENDP
最好是避免过程间标签。例如,JB Only_Nums
从过程Token
的中间跳到过程MAIN
的中间。这被称为“意大利面条代码”,可能会导致麻烦。您至少在堆栈上留下Token
的返回地址。一位关注MAIN
的未来程序员不会知道这一点。