You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用GDB调试x86_64汇编:如何查看栈变量及地址差疑问

栈内存查看与汇编地址疑问解答

问题背景

调试以下C程序:

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

疑问:

  1. 变量x存在栈中,但用x/10x $rsp无法找到,如何正确打印栈?
  2. 上述地址之间的差值为何是16?

解答

1. 正确定位变量x的方法

变量x存储在rbp-0x4的内存位置,当前断点处rsp指向的是之前push rbp压入栈的旧rbp值(尚未执行pop rbp),因此直接查看$rsp指向的内存看不到x。你需要以rbp为基准查看栈:

  • 直接定位x的地址:执行x/10x $rbp-0x4,会从x的存储地址开始,显示10个双字内存内容,其中第一个值就是0x5
  • 从栈帧基址开始查看:执行x/10x $rbp,输出内容中,$rbp指向的是旧rbp值,再往下4字节(即$rbp-0x4)就是x的值

也可以先通过p/x $rbp-0x4获取x的具体地址,再用x/wx [地址]命令单独查看该地址的内容,确认是否为0x5。

2. 地址差值为16的原因

你提到的16差值对应64位系统的16字节栈对齐规则,同时也和汇编指令的字节数累加有关:

  • 栈对齐要求:64位系统中,函数调用时栈必须保持16字节对齐。进入main函数后,push rbp使rsp减少8字节,打破了原本的对齐状态。编译器会预留足够的栈空间让整个栈帧大小为16字节的倍数——虽然x只需要4字节,但栈帧从rbp-0x10到rbp被预留(其中rbp-0x4存x,剩余12字节为填充空间),以此满足对齐要求。
  • 指令偏移量的16:汇编中<+0>到<+16>的偏移量是指令字节数的累加:push rbp占1字节、mov rbp,rsp占3字节、mov [rbp-0x4],0x5占7字节、mov eax,0x0占5字节,总和1+3+7+5=16,这是指令的总长度,和栈对齐的16字节是两个独立概念,容易混淆。

内容的提问来源于stack exchange,提问作者Irbis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 12:10:32