一個程式在運行程序中,函式呼叫時會向堆疊壓入: 原來暫存器ebp的值, 引數, 以及呼叫函式的下一個指令地址
在呼叫一個函式時, 編譯器就計算好函式需要的空間, 然后esp = ebp-需要的空間, 通過ebp+偏移量來訪問. 在函式里呼叫另外一個函式時, 原來fun的ebp值壓堆疊

#include<stdio.h>
intfun(inta,intb)
{intc = a+b;returnc;}
intmain(void)
{ fun(123,456);intd =98;printf("%d\n", d);}
此程式的匯編是:
0000000100000f30<_fun>:
100000f30: 55 push %rbp
100000f31: 48 89 e5 mov %rsp,%rbp
100000f34: 89 7d fc mov %edi,-0x4(%rbp)
100000f37: 89 75 f8 mov %esi,-0x8(%rbp)
如果你在學習C/C++的程序中遇到了問題,可以來加入小編的企鵝圈問小編哦~小編很熱情的(●’?’●)
100000f3a: 8b 75 fc mov -0x4(%rbp),%esi
100000f3d:03 75 f8 add -0x8(%rbp),%esi
100000f40:89 75 f4 mov %esi,-0xc(%rbp)
100000f43:8b 45 f4 mov -0xc(%rbp),%eax
100000f46:5d pop %rbp
100000f47:c3 retq
100000f48:0f 1f 84 00 00 00 00 nopl 0x0(%rax,%rax,1)
100000f4f:00

0000000100000f50<_main>:
100000f50:55 push %rbp
100000f51:48 89 e5 mov %rsp,%rbp
100000f54:48 83 ec 10 sub $0x10,%rsp
100000f58:bf 7b 00 00 00 mov $0x7b,%edi
100000f5d:be c8 01 00 00 mov $0x1c8,%esi
100000f62:e8 c9 ff ff ff callq 100000f30<_fun>
100000f67:48 8d 3d 44 00 00 00 lea 0x44(%rip),%rdi # 100000fb2<_main+0x62> 100000f6e:c7 45 fc 62 00 00 00 movl $0x62,-0x4(%rbp)
100000f75:8b 75 fc mov -0x4(%rbp),%esi
100000f78:89 45 f8 mov %eax,-0x8(%rbp)
100000f7b:b0 00 mov $0x0,%al
100000f7d:e8 0e 00 00 00 callq 100000f90<_main+0x40>
100000f82:31 f6 xor %esi,%esi
100000f84:89 45 f4 mov %eax,-0xc(%rbp)
100000f87:89 f0 mov %esi,%eax
100000f89:48 83 c4 10 add $0x10,%rsp
100000f8d:5d pop %rbp
100000f8e:c3 retq
對于以上的程式, 堆疊的布局是這樣的:

0x123 rbp(main)0x11f c0x11b b0x117 a0x113 rbp(foo) rsp(main,foo)100000f30<呼叫fun下一個指令地址>
粗略來說, 就是ebp指向堆疊底, esp指向堆疊頂第一個引數的地址, 在本例中就是&a
在呼叫一個函式時, 編譯器就計算好函式需要的空間, 然后esp = ebp-需要的空間, 通過ebp+偏移量來訪問
在函式里呼叫另外一個函式時, 原來fun的ebp值壓堆疊,
ebp = esp
esp = ebp-需要的空間

借此呼叫另外的函式
退出時會做函式呼叫時的逆操作, 看偽代碼:
pop ebp
esp = ebp
esp = ebp+需要的空間
內層函式是通過之前已經壓堆疊了的呼叫函式時的下一條指令來得知回傳地址的,
C/C++編程日記:匯編與C之間的關系
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/222687.html
標籤:其他
