I have 2 module files, one main file and one aux file. In the main file I call a procedure from the second module (which reads a number from the keyboard and stores it in AX). When I debug the code, I notice that when the code returns from the aux procedure to the main procedure, it goes in an infinite loop.
main.asm Module with main procedure:
EXTRN READNR:FAR
DATE SEGMENT PARA 'DATA'
EMPTY DB ?
DATE ENDS
CODEMAIN SEGMENT PARA 'CODE'
ASSUME CS: CODEMAIN, DS: DATE
MAINPROC PROC FAR
PUSH DS
XOR AX, AX
PUSH AX
MOV AX, DATE
MOV DS, AX
CALL READNR
RET
MAINPROC ENDP
CODEMAIN ENDS
END MAINPROC
aux.asm Module with aux procedure:
DATA SEGMENT PARA 'DATA'
NUMBER DB 6, ?, 6 DUP(?)
DATA ENDS
AUX SEGMENT PARA 'CODE'
PUBLIC READNR
ASSUME CS: AUX, DS: DATA
READNR PROC FAR
PUSH AX
XOR AX, AX
PUSH DS
MOV AX, DATA
MOV DS, AX
MOV DX, OFFSET NUMBER
MOV AH, 0Ah
INT 21h
MOV BX, 10
MOV AX, 0
MOV CX, 0
MOV SI, 2
MOV CL, NUMBER[1]
LOOP1:
MUL BX
ADD AL, NUMBER[SI]
SUB AL, 30h
INC SI
LOOP LOOP1
RET
READNR ENDP
AUX ENDS
END
I used these commands to link the 2 modules:
tasm main
tasm aux
tlink main aux
td main
Can you find out why it doesn't return correctly?
CodePudding user response:
READNR
is pushing twice and not ever popping. I don't see how it could possibly return to the caller.
So if I push on the stack in some module and the stack remains non-empty, the program will not return properly to the main module?
Yes: the call instruction pushes a return address onto the stack, and that's where the ret instruction looks for it — as the top item on the stack. If you modify the stack by pushing, then whatever you've pushed is now the top thing on the stack. In order to use return using ret
, a function must remove all the items placed onto the stack, restoring the stack pointer to the same value it had upon entry.
If you leave extra things on the stack, first the ret
will not work as expected, but even if somehow could get back to the caller, the caller would likely also have issues because callers expect the stack to be in the same state they left it.