我有以下组装程序:
.globl main
main:
push %rbp
mov %rsp, %rbp
movb $8, -1(%rbp)
movw $30, -4(%rbp)
mov -1(%rbp), %rax
add -4(%rbp), %rax
call func
pop %rbp
ret
func:
push %rbp
mov %rsp, %rbp
movl $7, -4(%rbp)
mov -4(%rbp), %rbx
pop %rbp
ret
当逐步执行程序时,在call func
之后,但在push %rbp
之前,当尝试访问rbp
的值时,它以前是$0x0800001e`(8字节、0字节、0比特、30字节(,现在显示全零:
>>> x/1xw $rbp-4
0x7fffffffe410: 0x00000000
为什么会出现这种情况?rbp
是否在函数调用之间重置其值(尽管保留其地址(?
RBP的值不变。每个asm指令仅按照手册中记录的方式更改机器的体系结构状态(寄存器+内存内容(。(英特尔和AMD都发布了PDF手册;指令集参考的HTML摘录来自IInel的PDFhttps://www.felixcloutier.com/x86/)
您正在转储RBP指向的内存,而不是打印RBP的值。(对p /x $rbp
执行此操作。或者对layout reg
使用GDB的TUI模式。请参阅https://stackoverflow.com/tags/x86/info用于GDB提示(。
当call
推送返回地址时,内存会发生变化。例如,使用sub $8, %rsp
时,您没有为本地变量保留任何空间,因此RSP=RBP,RSP下方的空间是push
和call
写入的位置。
这就是为什么非叶函数不能将红色区域(低于RSP(用于其本地变量的原因。