繼續上一篇文章,還是那個代碼,這次我們在Linux上編譯試試,看看和windows有什麽不同。
1int add(int a, int b) {
2 return a + b;
3}
4
5int main()
6{
7 int a = add(1, 2);
8 return 0;
9}
匯編來咯:
1 0x000055555555460e <+0>: push rbp
2 0x000055555555460f <+1>: mov rbp,rsp
3 0x0000555555554612 <+4>: sub rsp,0x10
4 0x0000555555554616 <+8>: mov esi,0x2
5 0x000055555555461b <+13>: mov edi,0x1
6 0x0000555555554620 <+18>: call 0x5555555545fa <add>
7 0x0000555555554625 <+23>: mov DWORD PTR [rbp-0x4],eax
8 0x0000555555554628 <+26>: mov eax,0x0
9 0x000055555555462d <+31>: leave
10 0x000055555555462e <+32>: ret
11
12 ;其實大差不差,前三句是保存上下文和開闢棧幀
13 ;後面把參數放進去,調用add,然後吧eax裏的返回值取出到rbp-4這個地址裏,清零
14 ;leave的看起來像是linux平臺下獨有的指令
15 ;這個指令其實基本等同于 mov rsp, rbp; pop rbp
16 ;實際上就是回復上下文
17
18
19 0x00005555555545fa <+0>: push rbp
20 0x00005555555545fb <+1>: mov rbp,rsp
21 0x00005555555545fe <+4>: mov DWORD PTR [rbp-0x4],edi
22 0x0000555555554601 <+7>: mov DWORD PTR [rbp-0x8],esi
23 0x0000555555554604 <+10>: mov edx,DWORD PTR [rbp-0x4]
24 0x0000555555554607 <+13>: mov eax,DWORD PTR [rbp-0x8]
25 0x000055555555460a <+16>: add eax,edx
26 0x000055555555460c <+18>: pop rbp
27 0x000055555555460d <+19>: ret
28
29 ;這裏也很簡單,前兩句還是保存上下文,不過這次沒有開闢棧幀
30 ;直接把兩個寄存器的值移動到内存地址裏再放在寄存器裏再計算?
31 ;這樣寫有點逆天,不過估計是debug模式完全沒有優化
32 ;最後彈出地址到棧裏返回