我可以像使用 CALL
和 RET
一样使用 JMP
和 RET
从标签跳回去吗?
当您使用 CALL 时,指令指针的当前值保存在堆栈上...当相应的 RET 执行时,它会从堆栈中获取地址并跳转到那里。如果您只是JMP而不将当前地址保存在堆栈上,则相应的RET将毫不奇怪地无法找到它期望的正确地址。它可能会找到一些数据,但是,它会尝试跳转到这些位表示的地址。在任何体面的处理器上,这都会导致某种形式的违规。
仅当您模仿 CALL 指令的作用时,才能跳转到过程并使用 RET 返回。
No. JMP
更改指令指针。 CALL
将当前 IP 推送到堆栈并更新指令指针。
如果您使用带有JMP
的RET
,您将根据当时堆栈上碰巧发生的事情返回到某个未知位置。
JMP
替换CALL
,但仍使用 RET
或作为RET
的替代品,这是一个更好的答案:
PUSH WORD CS:Call_Return
JMP My_Method
Call_Return:
... (cont)
My_Method:
...(some code)
RET
或
My_Method:
...(some code)
POP DX
JMP DX
这只是证明可以以许多不同的方式做同样的事情。这假设 16 位寻址(实际模式),在这种情况下确实会有所不同。 在 32 位/64 位寻址模式下,您需要相应地更改推送、弹出和 JMP 命令。
也许如果你使用这样的东西:
MOV BX,IP
ADD BX,10 ;If I am not mistaken mov=3bytes,add=3bytes jmp=3 bytes,push=1 byte
PUSH BX
JMP
然后:
RET