“错误A2006:未定义的符号,从主线代码调用的宏”

时间:2017-04-23 02:16:06

标签: assembly masm undefined-function

我正在尝试提供最终项目的骨架,这是一个FP计算器。但是,我遇到了一些麻烦。如果我编译这段代码,我会得到Picture of Error Messages。我不确定这是什么汇编,但我相信它的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

1 个答案:

答案 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的未来程序员不会知道这一点。