函數(shù)調(diào)用是通過棧來實現(xiàn)的,而且知道在棧中存放著該函數(shù)的局部變量。但是,對于棧的實現(xiàn)細(xì)節(jié)可能不一定清楚。本文將介紹一下在Linux平臺下函數(shù)棧是如何實現(xiàn)的。
棧幀的結(jié)構(gòu)
函數(shù)在調(diào)用的時候都是在棧空間上開辟一段空間以供函數(shù)使用,棧是由高地址向地地址的方向生長的,而且棧有其棧頂和棧底,入棧出棧的地方就叫做棧頂。
在x86系統(tǒng)的CPU中,rsp是棧指針寄存器,這個寄存器中存儲著棧頂?shù)牡刂?。rbp中存儲著棧底的地址。函數(shù)棧空間主要是由這兩個寄存器來確定的。
當(dāng)程序運行時,棧指針rsp可以移動,棧指針和幀指針rbp一次只能存儲一個地址,所以,任何時候,這一對指針指向的是同一個函數(shù)的棧幀結(jié)構(gòu)。
而幀指針rbp是不移動的,訪問棧中的元素可以用-4(%rbp)或者8(%rbp)訪問%rbp指針下面或者上面的元素。
測試代碼如下:
#include int sum (int a,int b) { int c = a + b; return c; } int main() { int x = 5,y = 10,z = 0; z = sum(x,y); printf("%drn",z); return 0; }
0000000000000000 : 0: 55 push %rbp 1: 48 89 e5 mov %rsp,%rbp 4: 89 7d ec mov %edi,-0x14(%rbp) # 參數(shù)傳遞 7: 89 75 e8 mov %esi,-0x18(%rbp) # 參數(shù)傳遞 a: 8b 55 ec mov -0x14(%rbp),%edx d: 8b 45 e8 mov -0x18(%rbp),%eax 10: 01 d0 add %edx,%eax 12: 89 45 fc mov %eax,-0x4(%rbp) # 局部變量 15: 8b 45 fc mov -0x4(%rbp),%eax # 存儲結(jié)果 18: 5d pop %rbp 19: c3 retq 000000000000001a : 1a: 55 push %rbp # 保存%rbp。rbp,棧底的地址 1b: 48 89 e5 mov %rsp,%rbp # 設(shè)置新的棧指針。rsp 棧指針,指向棧頂?shù)牡刂? 1e: 48 83 ec 10 sub $0x10,%rsp # 分配 16字節(jié)??臻g。%rsp = %rsp-16 22: c7 45 f4 05 00 00 00 movl $0x5,-0xc(%rbp) # 賦值 29: c7 45 f8 0a 00 00 00 movl $0xa,-0x8(%rbp) # 賦值 30: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%rbp) # 賦值 37: 8b 55 f8 mov -0x8(%rbp),%edx 3a: 8b 45 f4 mov -0xc(%rbp),%eax 3d: 89 d6 mov %edx,%esi # 參數(shù)傳遞 ,從右向左 3f: 89 c7 mov %eax,%edi # 參數(shù)傳遞 41: e8 00 00 00 00 callq 46 # 調(diào)用sum 46: 89 45 fc mov %eax,-0x4(%rbp) 49: 8b 45 fc mov -0x4(%rbp),%eax # 存儲計算結(jié)果 4c: 89 c6 mov %eax,%esi 4e: 48 8d 3d 00 00 00 00 lea 0x0(%rip),%rdi # 55 55: b8 00 00 00 00 mov $0x0,%eax 5a: e8 00 00 00 00 callq 5f 5f: b8 00 00 00 00 mov $0x0,%eax 64: c9 leaveq 65: c3 retq +0x45>+0x3b>+0x2c>
在函數(shù)被調(diào)用之前,調(diào)用者會為調(diào)用函數(shù)做準(zhǔn)備。首先,函數(shù)棧上開辟了16字節(jié)的空間,存儲定義的3個int型變量,建立了main函數(shù)的棧。
CALL指令內(nèi)部其實還暗含了一個將返回地址(即CALL指令下一條指令的地址)壓棧的動作(由硬件完成)。
具體來說,call指令執(zhí)行時,先把下一條指令的地址入棧,再跳轉(zhuǎn)到對應(yīng)函數(shù)執(zhí)行的起始處。
審核編輯:湯梓紅
-
嵌入式系統(tǒng)
+關(guān)注
關(guān)注
41文章
3613瀏覽量
129622 -
Linux
+關(guān)注
關(guān)注
87文章
11332瀏覽量
210023 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4344瀏覽量
62839
發(fā)布評論請先 登錄
相關(guān)推薦
評論