寄存器传值——函数剖析
现象
实验环境:Ubuntu20,x86-64指令集
#include <stdio.h>int sum(int a, int b){return a+b;
}int main() {int aa = sum(5,3);printf("%d, %d\n", 9);return 0;
}
编译器提示我们 printf()函数少一个参数,但是我们发现一个有趣的现象,最终的程序的输出是9,5
,为什么第二个数不是一个随机值呢。而且这个 5 前面也出现过,会不会有什么关联呢?
实验剖析
打开 GDB,我们结合着对应的汇编代码进行查看:
call 之后,我们可以发现sum 函数为了实现加法操作对%edx进行了赋值:
当 sum 函数执行完成之后程序继续执行,在调用printf函数的时候,需要分别通过rdi,rsi,rdx三个寄存器传递相关参数,其中 rdi 存储的是格式化字符串地址,rsi 存储的是 9,但是由于我们并没有传入第三个参数,因此 edx中保存的是sum 函数里给 edx 赋值的 5。最终会导致 printf 使用了来自上面修改后的 edx 值。
附录
- GDB 常用命令
$ g++ -g -o your_program your_program.cpp # 编译带调试信息的 code
$ gdb ./your_program # 启动 GDB
(gdb) break main # 在 main 函数设置断点 b main
(gdb) run # 运行程序
(gdb) disassemble # 查看当前汇编代码 或者是 layout split
(gdb) stepi # 单步执行汇编指令
(gdb) info registers # 查看寄存器状态
(gdb) x/10x 0x400500 # 查看内存内容
(gdb) continue # 继续运行程序
-
x86寄存器指令集一栏
https://www.cnblogs.com/curiositywang/p/17681647.html
-
函数调用过程详解
https://www.cnblogs.com/curiositywang/p/18223331