当我使用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
我的问题是:
可以使用far调用在当前段中调用函数吗?
在调用堆栈中是否有错误的返回地址的已知原因?
答案 0 :(得分:1)
我建议不要使用kg
或k
在VirtualBox的调试器中遍历调用堆栈,除非您已紧跟设置函数堆栈框架的函数序言之后的地方:
push bp
mov bp, sp
在某些代码中,这是使用等效的ENTER
指令完成的。
VirtualBox的调用堆栈转储程序遍历堆栈,这要求将BP设置为当前堆栈帧。如果在输入函数后立即停止,则应考虑使用dw ss:sp
之类的命令,该命令会将来自当前堆栈指针位置的原始转储数据作为16位字。如果进行近距离呼叫,则第一个打印的单词应为返回的偏移量,远距离呼叫时,偏移量将首先跟随,然后是返回至的段
注意:我的经验是,假设已经完成FAR CALL才能遍历调用堆栈,所以NEAR CALL可能不会产生正确的调用堆栈跟踪。