寄存器传值——函数剖析

寄存器传值——函数剖析

现象

实验环境: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;
}

image-20240925103512436

编译器提示我们 printf()函数少一个参数,但是我们发现一个有趣的现象,最终的程序的输出是9,5,为什么第二个数不是一个随机值呢。而且这个 5 前面也出现过,会不会有什么关联呢?

实验剖析

打开 GDB,我们结合着对应的汇编代码进行查看:

image-20240925104918885

call 之后,我们可以发现sum 函数为了实现加法操作对%edx进行了赋值:

image-20240925105153288

当 sum 函数执行完成之后程序继续执行,在调用printf函数的时候,需要分别通过rdi,rsi,rdx三个寄存器传递相关参数,其中 rdi 存储的是格式化字符串地址,rsi 存储的是 9,但是由于我们并没有传入第三个参数,因此 edx中保存的是sum 函数里给 edx 赋值的 5。最终会导致 printf 使用了来自上面修改后的 edx 值。

image-20240925105746573

附录

  1. 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         # 继续运行程序

image-20240925104119447

  1. x86寄存器指令集一栏

    https://www.cnblogs.com/curiositywang/p/17681647.html

  2. 函数调用过程详解

    https://www.cnblogs.com/curiositywang/p/18223331

posted @ 2024-09-25 10:59  CuriosityWang  阅读(2)  评论(0编辑  收藏  举报