对于这样一份 C 代码:shell
int add (int a, int b) {
return a + b;
}
int main (void) {
int a = 10;
int b = 20;
int c = add(a, b);
return c;
}
先使用 gcc 编译函数
$ gcc -g -O0 hello.c -o hello
而后使用 objdump 来查看反汇编
只摘取其中结果中最重要的汇编代码,# 以后的内容为手动加的注释code
$ objdump -j .text -d hello
00000000004004ed :
4004ed: 55 push %rbp # 将 rbp 寄存器的值压入栈
4004ee: 48 89 e5 mov %rsp,%rbp # 将 rsp 寄存器的值 移动到 rbp 寄存器,栈底(rbp)移动到原来的栈顶的位置(rsp)
4004f1: 89 7d fc mov %edi,-0x4(%rbp) # 将 edi 寄存器的值,移动到 -0x4(相对于 rbp 的地址)
4004f4: 89 75 f8 mov %esi,-0x8(%rbp) # 将 esi 寄存器的值,移动到 -0x8(相对于 rbp 的地址)
4004f7: 8b 45 f8 mov -0x8(%rbp),%eax # 将 -0x8 的值移动到 eax
4004fa: 8b 55 fc mov -0x4(%rbp),%edx # 将 -0x4 的值移动到 edx
4004fd: 01 d0 add %edx,%eax # eax += edx
}
4004ff: 5d pop %rbp # 从栈顶弹出一个值,放到 rbp 里
400500: c3 retq # 从栈顶弹出一个值,放到 rip 里,也就是至关于 pop %rip
0000000000400501 :
400501: 55 push %rbp # 将 rbp 压入栈
400502: 48 89 e5 mov %rsp,%rbp # 将 rsp 寄存器的值 移动到 rbp 寄存器,栈底(rbp)移动到原来的栈顶的位置(rsp)
400505: 48 83 ec 10 sub $0x10,%rsp # rsp -= 0x10,栈顶向下生长高度 0x10
400509: c7 45 fc 0a 00 00 00 movl $0xa,-0x4(%rbp) # 将整数 0xa 移动到 -0x4(相对于 rbp)
400510: c7 45 f8 14 00 00 00 movl $0x14,-0x8(%rbp) # 将整数 0x14 移动到 -0x8(相对于 rbp)
400517: 8b 55 f8 mov -0x8(%rbp),%edx # 将 -0x8 移动到 edx
40051a: 8b 45 fc mov -0x4(%rbp),%eax # 将 -0x4 移动到 eax
40051d: 89 d6 mov %edx,%esi # esi = edx
40051f: 89 c7 mov %eax,%edi # edi = eax
400521: e8 c7 ff ff ff callq 4004ed # 调用函数 add
400526: 89 45 f4 mov %eax,-0xc(%rbp) # 将 eax 移动到 -0xc
400529: 8b 45 f4 mov -0xc(%rbp),%eax # 将 -0xc 移动到 eax
40052c: c9 leaveq # 至关于movq %rbp, %rsp + popq %rbp,将 rbp 和 rsp 回退到上一帧
40052d: c3 retq # 从栈顶弹出一个值,放到 rip 里,也就是至关于 pop %rip
40052e: 66 90 xchg %ax,%ax # nop