x86 I386 AT&T汇编:栈首个压入值的GDB调试内存疑问
x86汇编栈操作与GDB内存查看疑问解答
问题场景
编写AT&T格式的x86 i386汇编程序,逻辑为:通过pushl指令将85压入栈,立即用popl弹出,随后程序退出。使用GNU汇编器as链接生成可执行文件后,用GDB调试:
- 在
_start处设断点,执行前esp指向0xffffcb60 - 执行
pushl $85后esp变为0xffffcb5c - 查看内存时,
x/d 0xffffcb5c得到85符合预期,但x/d 0xffffcb60得到1而非预期值
疑问:按理解,esp指向栈顶,压入值应存于0xffffcb5c至0xffffcb58,为何读取0xffffcb60得到1?是否x/d命令读取的是指定地址前4字节?
解答
- 关于GDB
x/d命令的误解:x/d是从指定地址开始读取4字节(i386架构下默认读取长度为long型,即4字节)并以十进制显示,完全不是“读取指定地址前4字节”。你指定0xffffcb60,就会读取该地址起始的4字节内容。 - 0xffffcb60的值来源:这个地址是push操作前的栈顶,push后栈顶下移到
0xffffcb5c,0xffffcb60属于栈的“未被本次操作覆盖”的区域,这里的1是程序启动时栈初始化的残留数据,和你本次push的85没有任何关系。你push的85仅存储在0xffffcb5c起始的4字节内存中,0xffffcb60不在这个范围内,它的值本来就不是你操作的目标数据。 - 验证方法:可以执行
x/2d 0xffffcb5c命令,会看到两个连续的4字节单元:0xffffcb5c对应85,0xffffcb60对应1,这清晰说明二者是独立的内存单元,存储的是不同内容。
内容的提问来源于stack exchange,提问作者Hoax
相关产品推荐
相关产品推荐

