Jordan
Jordan

Reputation: 21

"Error A2006: Undefined Symbol, Macro Called From, Main Line Code"

I am trying to provide a skeleton frame of a final project, which is a FP calculator. However, I've run into some trouble. If I compile this code, I get Picture of Error Messages. I am unsure what assembly this is, but I believe its 32bit and am using MASM compiler.

The point of this is to read a line from the input file, and make perform operations. However, I am only doing the defining section, my partners will figure out implementing the operations.

If I were to comment out the main function, minus "Only_Nums, Character_Error:, and Invalid_Char:" the program will compile.

Can you help me in determining why it won't compile. The only logical thing I can think of is that the code being referenced wasn't defined first, however, it was.

Thanks!

Edit: Replaced ESI with SI

.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

Upvotes: 2

Views: 1829

Answers (1)

rkhb
rkhb

Reputation: 14399

The rejected symbols are located inside a procedure (PROC..ENDP) and therefore local for a newer MASM. They are unknown outside the procedure.

If you double the colon (::) you declare that label as "global":

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

Better is to avoid interprocedural labels. For example, JB Only_Nums jumps from the middle of the procedure Token right into the middle of the procedure MAIN. This is called "spaghetti code" and can lead to trouble. You leave at least the return addres of Token on the stack. A future programmer who looks at MAIN won't know that.

Upvotes: 2

Related Questions