assembly - 离开后的基指针值
问题描述
我检查了以下简单可执行文件(ELF,X86-64)的寄存器值。你能解释一下为什么“离开”之后“rbp”是“0x7ffd222f1e80”吗?
我知道“离开”是指以下两条指令。
mov %rbp,%rsp
pop %rbp
所以我期望这个值。
mov $1, %eax
rax 0x1 1
rbp 0x7ffd222f1e70 0x7ffd222f1e70
rsp 0x7ffd222f1e70 0x7ffd222f1e70
leave
rax 0x1 1
rbp 0x7ffd222f1e70 0x7ffd222f1e70
rsp 0x7ffd222f1e78 0x7ffd222f1e78
// main.c
#include <stdio.h>
int f();
int main() {
return f();
}
// 函数
.data
.text
.global f
f:
push %rbp
mov %rsp, %rbp
mov $1, %eax
leave
ret
// 编译和调试
# gcc -g main.c func.s -o main
# gdb ./main
# b main
# b f
# r
# s
# i all
// 登记
main
rax 0x55dced86d5fa 94407366202874
rbp 0x7ffd222f1e80 0x7ffd222f1e80
rsp 0x7ffd222f1e80 0x7ffd222f1e80
f
rax 0x0 0
rbp 0x7ffd222f1e80 0x7ffd222f1e80
rsp 0x7ffd222f1e78 0x7ffd222f1e78
push %rbp
rax 0x0 0
rbp 0x7ffd222f1e80 0x7ffd222f1e80
rsp 0x7ffd222f1e70 0x7ffd222f1e70
mov %rsp, %rbp
rax 0x0 0
rbp 0x7ffd222f1e70 0x7ffd222f1e70
rsp 0x7ffd222f1e70 0x7ffd222f1e70
mov $1, %eax
rax 0x1 1
rbp 0x7ffd222f1e70 0x7ffd222f1e70
rsp 0x7ffd222f1e70 0x7ffd222f1e70
leave
rax 0x1 1
rbp 0x7ffd222f1e80 0x7ffd222f1e80 (???)
rsp 0x7ffd222f1e78 0x7ffd222f1e78
ret
rax 0x1 1
rbp 0x7ffd222f1e80 0x7ffd222f1e80
rsp 0x7ffd222f1e80 0x7ffd222f1e80
// 堆
-----------------
0x7ffd222f1e70
-----------------
0x7ffd222f1e78
-----------------
0x7ffd222f1e80
-----------------
解决方案
我意识到我没有正确理解“call”、“pop”和“ret”指令。现在我想我明白了。
程序和调用堆栈
https://courses.cs.washington.edu/courses/cse351/12au/lecture-slides/07-procedures.pdf
1 在调用 f() 之前:
rax 0x55ce8dc245fa 94345629943290
rbp 0x7fff30b035b0 0x7fff30b035b0
rsp 0x7fff30b035b0 0x7fff30b035b0
rip 0x55ce8dc245fe 0x55ce8dc245fe <main+4>
--------------|--------------
ADDRESS |VALUE
--------------|--------------
0x7fff30b035b0| <= rsp, rbp
--------------|--------------
2 开始调用 f():
rax 0x0 0
rbp 0x7fff30b035b0 0x7fff30b035b0
rsp 0x7fff30b035a8 0x7fff30b035a8
rip 0x55ce8dc2460a 0x55ce8dc2460a <f>
--------------|--------------
ADDRESS |VALUE
--------------|--------------
0x7fff30b035b0| <= rbp
--------------|--------------
0x7fff30b035a8|0x55ce8dc245fe <= rsp
--------------|--------------
3 推%rbp:
rax 0x0 0
rbp 0x7fff30b035b0 0x7fff30b035b0
rsp 0x7fff30b035a0 0x7fff30b035a0
rip 0x55ce8dc2460e 0x55ce8dc2460e <f+4>
--------------|--------------
ADDRESS |VALUE
--------------|--------------
0x7fff30b035b0| <= rbp
--------------|--------------
0x7fff30b035a8|0x55ce8dc245fe
--------------|--------------
0x7fff30b035a0|0x7fff30b035b0 <= rsp
--------------|--------------
4 mov %rsp, %rbp:
rax 0x0 0
rbp 0x7fff30b035a0 0x7fff30b035a0
rsp 0x7fff30b035a0 0x7fff30b035a0
rip 0x55ce8dc2460e 0x55ce8dc2460e <f+4>
--------------|--------------
ADDRESS |VALUE
--------------|--------------
0x7fff30b035b0|
--------------|--------------
0x7fff30b035a8|0x55ce8dc245fe
--------------|--------------
0x7fff30b035a0|0x7fff30b035b0 <= rsp, rbp
--------------|--------------
5 mov $1, %eax:
rax 0x1 1
rbp 0x7fff30b035a0 0x7fff30b035a0
rsp 0x7fff30b035a0 0x7fff30b035a0
rip 0x55ce8dc24613 0x55ce8dc24613 <f+9>
--------------|--------------
ADDRESS |VALUE
--------------|--------------
0x7fff30b035b0|
--------------|--------------
0x7fff30b035a8|0x55ce8dc245fe
--------------|--------------
0x7fff30b035a0|0x7fff30b035b0 <= rsp, rbp
--------------|--------------
6离开:(mov %rbp %rsp,pop %rbp)
rax 0x1 1
rbp 0x7fff30b035b0 0x7fff30b035b0
rsp 0x7fff30b035a8 0x7fff30b035a8
rip 0x55ce8dc24614 0x55ce8dc24614 <f+10>
--------------|--------------
ADDRESS |VALUE
--------------|--------------
0x7fff30b035b0| <= rbp
--------------|--------------
0x7fff30b035a8|0x55ce8dc245fe <= rsp
--------------|--------------
7 回复:
rax 0x1 1
rbp 0x7fff30b035b0 0x7fff30b035b0
rsp 0x7fff30b035b0 0x7fff30b035b0
rip 0x55ce8dc24608 0x55ce8dc24608 <main+14>
--------------|--------------
ADDRESS |VALUE
--------------|--------------
0x7fff30b035b0| <= rbp, rsp
--------------|--------------
推荐阅读
- javascript - 如何修复链接引导模板?
- r - 将字符串中的单词提取到不同的字符串中
- xcode - 这些红色靶心图标在 Xcode 中是什么意思?
- python-3.x - 通过 tkinter 在 mysql 表中输入记录的代码没有给出正确的输出
- html - 将 6 个图像彼此相邻对齐
- r - 如何使用 mgcv 包中的 predict.gam 计算一阶导数
- javascript - ReferenceError: axios 未定义
- flutter - Webview 未随 setState 更改而更新
- python - 使用 beautifulsoup 抓取动态加载页面
- django - 如何在 Django 管理员 ListView 中将 True 值更改为绿色检查