Last Regrets

看一眼Linux的匯編

· sdttttt

繼續上一篇文章,還是那個代碼,這次我們在Linux上編譯試試,看看和windows有什麽不同。

int add(int a, int b) {
	return a + b;
}

int main()
{
	int a = add(1, 2);
	return 0;
}

匯編來咯:

   0x000055555555460e <+0>:	push   rbp
   0x000055555555460f <+1>:	mov    rbp,rsp
   0x0000555555554612 <+4>:	sub    rsp,0x10
   0x0000555555554616 <+8>:	mov    esi,0x2
   0x000055555555461b <+13>:	mov    edi,0x1
   0x0000555555554620 <+18>:	call   0x5555555545fa <add>
   0x0000555555554625 <+23>:	mov    DWORD PTR [rbp-0x4],eax
   0x0000555555554628 <+26>:	mov    eax,0x0
   0x000055555555462d <+31>:	leave
   0x000055555555462e <+32>:	ret
   
   ;其實大差不差,前三句是保存上下文和開闢棧幀
   ;後面把參數放進去,調用add,然後吧eax裏的返回值取出到rbp-4這個地址裏,清零
   ;leave的看起來像是linux平臺下獨有的指令
   ;這個指令其實基本等同于 mov rsp, rbp; pop rbp
   ;實際上就是回復上下文
   
   
   0x00005555555545fa <+0>:	push   rbp
   0x00005555555545fb <+1>:	mov    rbp,rsp
   0x00005555555545fe <+4>:	mov    DWORD PTR [rbp-0x4],edi
   0x0000555555554601 <+7>:	mov    DWORD PTR [rbp-0x8],esi
   0x0000555555554604 <+10>:	mov    edx,DWORD PTR [rbp-0x4]
   0x0000555555554607 <+13>:	mov    eax,DWORD PTR [rbp-0x8]
   0x000055555555460a <+16>:	add    eax,edx
   0x000055555555460c <+18>:	pop    rbp
   0x000055555555460d <+19>:	ret
   
   ;這裏也很簡單,前兩句還是保存上下文,不過這次沒有開闢棧幀
   ;直接把兩個寄存器的值移動到内存地址裏再放在寄存器裏再計算?
   ;這樣寫有點逆天,不過估計是debug模式完全沒有優化
   ;最後彈出地址到棧裏返回