在我看来,x86_64调用约定规定
返回地址
,也称为保存的$rip
应该在当前帧基址$rbp
正上方 - 例如:8(%rbp) return address
0(%rbp) previous %rbp value
x86_64调用约定的参考资料: http://6.035.scripts.mit.edu/sp16/x86-64-architecture-guide.html http://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64/
然而,我从一个进程的gdb
中获得的帧和$rbp
寄存器对我来说没有意义:
寄存器:
(gdb) info registers
rax 0xfffffffffffffffc -4
rbx 0x7ff7143fbc40 140699173370944
rcx 0xffffffffffffffff -1
rdx 0x80 128
rsi 0x7ff7143fb4e0 140699173369056
rdi 0x9 9
rbp 0x7ff7143fbb00 0x7ff7143fbb00
rsp 0x7ff7143fb4c0 0x7ff7143fb4c0
r8 0x7ff715e2a630 140699200824880
r9 0xa072 41074
r10 0x493e0 300000
r11 0x293 659
r12 0x7ff715e2a600 140699200824832
r13 0x7ff715e2a630 140699200824880
r14 0x7ff7143fb4e0 140699173369056
r15 0x7ff715c73078 140699199025272
rip 0x7ff71d466f33 0x7ff71d466f33 <epoll_wait+51>
eflags 0x293 [ CF AF SF IF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
框架:
(gdb) info frame
Stack level 0, frame at 0x7ff7143fb4d0:
rip = 0x7ff71d466f33 in epoll_wait; saved rip = 0x459347
called by frame at 0x7ff7143fbb10
Arglist at 0x7ff7143fb4b8, args:
Locals at 0x7ff7143fb4b8, Previous frame's sp is 0x7ff7143fb4d0
Saved registers:
rip at 0x7ff7143fb4c8
如果我从堆栈指针($rsp
, $rsp+0x8
, $rsp+0x10
,等)遍历回去,我应该能在堆栈上找到保留的$rip
。好消息是 - 我找到了!
(gdb) x/8x 0x7ff7143fb4c8
0x7ff7143fb4c8: 0x47 0x93 0x45 0x00 0x00 0x00 0x00 0x00
问题:
您可以在此处看到,地址为0x7ff7143fb4c8
的8字节内存与gdb中info frame
的saved $rip
完全相同。根据这个,根据x86_64调用约定,$rbp
的值不应该是0x7ff7143fb4c0
吗?为什么当前的$rbp
是0x7ff7143fbb00
?能否有人帮助填补这个空白?