经过一些额外的推送后,我来自另一个模块的程序无法 return 正确地转换为来自主模块的主程序
My procedure from another module does not return correctly to main procedure from main module, after some extra pushes
我有2个模块文件,一个主文件和一个辅助文件。在主文件中,我从第二个模块调用一个过程(它从键盘读取一个数字并将其存储在 AX 中)。当我调试代码时,我注意到当代码 returns 从 aux 过程到 main 过程时,它进入无限循环。
main.asm 包含主要过程的模块:
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 带有辅助程序的模块:
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
我使用这些命令 link 2 个模块:
tasm main
tasm aux
tlink main aux
td main
你能找出它 return 不正确的原因吗?
READNR
推了两次,但没有弹出。我不明白它怎么可能 return 给来电者。
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?
是的:call 指令将 return 地址压入堆栈,这就是 ret 指令查找它的地方 — 作为堆栈的顶部项目。如果您通过压入修改堆栈,那么您压入的任何内容现在都位于堆栈的顶部。为了使用 ret
使用 return,函数必须删除所有放置在堆栈上的项目,将堆栈指针恢复到与进入时相同的值。
如果你在堆栈上留下额外的东西,首先 ret
将不会按预期工作,但即使以某种方式可以返回给调用者,调用者也可能会有问题,因为调用者期望堆栈保持他们离开时的状态。
我有2个模块文件,一个主文件和一个辅助文件。在主文件中,我从第二个模块调用一个过程(它从键盘读取一个数字并将其存储在 AX 中)。当我调试代码时,我注意到当代码 returns 从 aux 过程到 main 过程时,它进入无限循环。
main.asm 包含主要过程的模块:
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 带有辅助程序的模块:
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
我使用这些命令 link 2 个模块:
tasm main
tasm aux
tlink main aux
td main
你能找出它 return 不正确的原因吗?
READNR
推了两次,但没有弹出。我不明白它怎么可能 return 给来电者。
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?
是的:call 指令将 return 地址压入堆栈,这就是 ret 指令查找它的地方 — 作为堆栈的顶部项目。如果您通过压入修改堆栈,那么您压入的任何内容现在都位于堆栈的顶部。为了使用 ret
使用 return,函数必须删除所有放置在堆栈上的项目,将堆栈指针恢复到与进入时相同的值。
如果你在堆栈上留下额外的东西,首先 ret
将不会按预期工作,但即使以某种方式可以返回给调用者,调用者也可能会有问题,因为调用者期望堆栈保持他们离开时的状态。