远程调用将错误的 IP 推送到堆栈
Far call pushing wrong IP to the stack
当我在实模式下使用 VirtualBox 运行 以下代码时,我希望 call 0x9000:foo
指令将 CS 和 IP 寄存器压入堆栈。然而,当我在远调用之后查看调用堆栈(在 VirtualBox 的调试器中)时,return 地址被设置为 9000:000006c6
(而不是 9000:0000078c
),显然是一个任意地址。
如果我使用近调用,则调用堆栈中的 return 地址设置正确。
我正在使用 NASM 和 运行在 VirtualBox 上以 x86 实模式编译代码。
我知道在这个例子中我不需要远程调用,但我的代码的另一部分需要它。
9000:00000787 call 0x9000:foo
9000:........ ...
9000:00003bac push bp ; foo:
9000:........ ...
9000:00003bf0 retf
我的问题是:
使用far call调用当前段的函数可以吗?
调用堆栈中的 return 地址错误是否有已知原因?
我建议不要使用 kg
或 k
在 VirtualBox 的调试器中遍历调用堆栈,除非你已经进入了设置函数堆栈框架的函数序言之后的某个点:
push bp
mov bp, sp
在某些代码中,这是使用等效的 ENTER
指令完成的。
VirtualBox 的调用堆栈转储器遍历堆栈,这需要将 BP 设置为当前堆栈帧。如果你在进入一个函数后立即停止,你应该考虑像 dw ss:sp
这样的命令,它会将当前堆栈指针位置的数据原始转储为 16 位字。如果进行近距离调用,则打印的第一个单词应该是 return 到 return 的偏移量,对于远距离调用,偏移量将首先紧随其后的是 return 到
的段
注意:根据我的经验,调用堆栈是在假设已完成 FAR CALL 以到达函数的情况下遍历的,而 NEAR CALL 可能不会产生正确的调用堆栈跟踪。
当我在实模式下使用 VirtualBox 运行 以下代码时,我希望 call 0x9000:foo
指令将 CS 和 IP 寄存器压入堆栈。然而,当我在远调用之后查看调用堆栈(在 VirtualBox 的调试器中)时,return 地址被设置为 9000:000006c6
(而不是 9000:0000078c
),显然是一个任意地址。
如果我使用近调用,则调用堆栈中的 return 地址设置正确。
我正在使用 NASM 和 运行在 VirtualBox 上以 x86 实模式编译代码。
我知道在这个例子中我不需要远程调用,但我的代码的另一部分需要它。
9000:00000787 call 0x9000:foo
9000:........ ...
9000:00003bac push bp ; foo:
9000:........ ...
9000:00003bf0 retf
我的问题是:
使用far call调用当前段的函数可以吗?
调用堆栈中的 return 地址错误是否有已知原因?
我建议不要使用 kg
或 k
在 VirtualBox 的调试器中遍历调用堆栈,除非你已经进入了设置函数堆栈框架的函数序言之后的某个点:
push bp
mov bp, sp
在某些代码中,这是使用等效的 ENTER
指令完成的。
VirtualBox 的调用堆栈转储器遍历堆栈,这需要将 BP 设置为当前堆栈帧。如果你在进入一个函数后立即停止,你应该考虑像 dw ss:sp
这样的命令,它会将当前堆栈指针位置的数据原始转储为 16 位字。如果进行近距离调用,则打印的第一个单词应该是 return 到 return 的偏移量,对于远距离调用,偏移量将首先紧随其后的是 return 到
注意:根据我的经验,调用堆栈是在假设已完成 FAR CALL 以到达函数的情况下遍历的,而 NEAR CALL 可能不会产生正确的调用堆栈跟踪。