對於這樣一份 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 <add>: 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 <main>: 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> # 調用函數 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