我调试了以下简单程序的汇编代码:
int main()
{
int x = 5;
return 0;
}
我在return语句上设置了断点。gdb显示了以下汇编代码(intel语法):
(gdb) disass
Dump of assembler code for function main():
0x00005555555545fa <+0>: push rbp
0x00005555555545fb <+1>: mov rbp,rsp
0x00005555555545fe <+4>: mov DWORD PTR [rbp-0x4],0x5
=> 0x0000555555554605 <+11>: mov eax,0x0
0x000055555555460a <+16>: pop rbp
0x000055555555460b <+17>: ret
End of assembler dump.
以下是有关rsp寄存器的信息:
(gdb) info reg rsp
rsp 0x7fffffffdcb0 0x7fffffffdcb0
变量x的值应该放在堆栈上,如何打印堆栈?我尝试了下面的命令,但没有成功:
(gdb) x/10x $rsp
0x7fffffffdcb0: 0x55554610 0x00005555 0xf7a03c87 0x00007fff
0x7fffffffdcc0: 0x00000001 0x00000000 0xffffdd98 0x00007fff
0x7fffffffdcd0: 0x00008000 0x00000001
此外,我不明白为什么上述地址之间的差异等于16。
1条答案
按热度按时间rur96b6h1#
x变量的值应该放在堆栈上,如何打印堆栈?
你看到的是一个叫做red zone的东西--任何函数都可以使用堆栈指针 * 之下 * 的一些堆栈空间。这是ABI级别的优化--只有在调用另一个函数或超出红色区域(SysV ABI上为128字节)时才需要移动堆栈指针。
请注意,该值存储在帧指针
rbp
(此处等于堆栈指针rsp
)* 以下 * 4个字节处。因此,请尝试从
$rsp - 4
或更小的位置开始打印堆栈。或者使用
-mno-red-zone
编译(但请注意,在SysV上,ABI堆栈指针在16个字节上对齐,因此您的值可能位于$rsp + 12
)。此外,我不明白为什么上述地址之间的差异等于16
内存转储每行包含16个字节(见4个值,每个值4个字节)。因此下一行在16个字节后开始(或0x 10)。使用
x/10x
,您请求打印10个十六进制值(默认为dwords),因此您将打印40个字节的内存。可以使用
x/wx $rsp-4
打印单个双字值。有关更多详细信息,请参阅GDB docs - Memory。