跳入新函数后 rbp 的值发生变化
Value of rbp changing after jumping into a new function
我有以下汇编程序:
.globl main
main:
push %rbp
mov %rsp, %rbp
movb , -1(%rbp)
movw , -4(%rbp)
mov -1(%rbp), %rax
add -4(%rbp), %rax
call func
pop %rbp
ret
func:
push %rbp
mov %rsp, %rbp
movl , -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 instruction-set 参考摘自 Iinel 在 https://www.felixcloutier.com/x86/ 的 PDF)
您正在通过 RBP 转储内存 pointed-to,而不是打印 RBP 的值。 (使用 p /x $rbp
执行此操作。或者使用 layout reg
的 GDB 的 TUI 模式。请参阅 https://whosebug.com/tags/x86/info 的底部以获取 GDB 提示)。
当call
压入一个return 地址 时内存发生变化。例如,您没有使用 sub , %rsp
为本地变量保留任何 space,因此 RSP = RBP 和 RSP 下面的 space 是 push
和 call
写。
这就是为什么 non-leaf 函数不能将 red-zone(低于 RSP)用于其局部变量。
我有以下汇编程序:
.globl main
main:
push %rbp
mov %rsp, %rbp
movb , -1(%rbp)
movw , -4(%rbp)
mov -1(%rbp), %rax
add -4(%rbp), %rax
call func
pop %rbp
ret
func:
push %rbp
mov %rsp, %rbp
movl , -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 instruction-set 参考摘自 Iinel 在 https://www.felixcloutier.com/x86/ 的 PDF)
您正在通过 RBP 转储内存 pointed-to,而不是打印 RBP 的值。 (使用 p /x $rbp
执行此操作。或者使用 layout reg
的 GDB 的 TUI 模式。请参阅 https://whosebug.com/tags/x86/info 的底部以获取 GDB 提示)。
当call
压入一个return 地址 时内存发生变化。例如,您没有使用 sub , %rsp
为本地变量保留任何 space,因此 RSP = RBP 和 RSP 下面的 space 是 push
和 call
写。
这就是为什么 non-leaf 函数不能将 red-zone(低于 RSP)用于其局部变量。