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