函數調用是通過棧來實現的,而且知道在棧中存放著該函數的局部變量。但是,對于棧的實現細節可能不一定清楚。本文將介紹一下在Linux平臺下函數棧是如何實現的。
棧幀的結構
函數在調用的時候都是在棧空間上開辟一段空間以供函數使用,棧是由高地址向地地址的方向生長的,而且棧有其棧頂和棧底,入棧出棧的地方就叫做棧頂。
在x86系統的CPU中,rsp是棧指針寄存器,這個寄存器中存儲著棧頂的地址。rbp中存儲著棧底的地址。函數棧空間主要是由這兩個寄存器來確定的。
當程序運行時,棧指針rsp可以移動,棧指針和幀指針rbp一次只能存儲一個地址,所以,任何時候,這一對指針指向的是同一個函數的棧幀結構。
而幀指針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) # 參數傳遞 7: 89 75 e8 mov %esi,-0x18(%rbp) # 參數傳遞 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 # 存儲結果 18: 5d pop %rbp 19: c3 retq 000000000000001a : 1a: 55 push %rbp # 保存%rbp。rbp,棧底的地址 1b: 48 89 e5 mov %rsp,%rbp # 設置新的棧指針。rsp 棧指針,指向棧頂的地址 1e: 48 83 ec 10 sub $0x10,%rsp # 分配 16字節棧空間。%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 # 參數傳遞 ,從右向左 3f: 89 c7 mov %eax,%edi # 參數傳遞 41: e8 00 00 00 00 callq 46 # 調用sum 46: 89 45 fc mov %eax,-0x4(%rbp) 49: 8b 45 fc mov -0x4(%rbp),%eax # 存儲計算結果 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>
在函數被調用之前,調用者會為調用函數做準備。首先,函數棧上開辟了16字節的空間,存儲定義的3個int型變量,建立了main函數的棧。

CALL指令內部其實還暗含了一個將返回地址(即CALL指令下一條指令的地址)壓棧的動作(由硬件完成)。
具體來說,call指令執行時,先把下一條指令的地址入棧,再跳轉到對應函數執行的起始處。
審核編輯:湯梓紅
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
嵌入式系統
+關注
關注
41文章
3747瀏覽量
133639 -
Linux
+關注
關注
88文章
11760瀏覽量
219039 -
函數
+關注
關注
3文章
4417瀏覽量
67516
發布評論請先 登錄
相關推薦
熱點推薦
嵌入式SIP協議棧怎么設計?
,憑借SIP自身的特性可有效提高嵌入式網絡設備的互操作性和接入網絡的便利性。但SIP協議本身只給出SIP消息的文法定義以及自然語言描述的消息處理,并未給出SIP協議棧的實現機制。這里討論在嵌入式終端設備上建立
發表于 10-29 08:14
嵌入式全棧知識體系相關資料分享
嵌入式是一門交叉學科。一個嵌入式電子產品(比如手機)從底層到上層,一般會涉及半導體芯片、電子電路、計算機、操作系統、多媒體等不同專業領域的知識。很多從事嵌入式開發的朋友,通常來自不同的
發表于 12-17 06:22
主流的小型嵌入式網絡協議棧
新產品、新技術也是層出不窮,本章節就為大家介紹當前主流的小型嵌入式網絡協議棧。目錄第1章 當前主流的小型嵌入式網絡協議棧1.1 當前主流的嵌入式
發表于 12-23 06:18
嵌入式VxWorks網絡協議棧的Mutiplexer接口及其使用方法
嵌入式系統網絡協議棧的靈活性在應用上是一個重要指標。介紹嵌入式實時操作系統VxWorks網絡協議棧
發表于 04-09 10:00
?10次下載
基于和欣嵌入式操作系統實現的一個構件化的網絡協議棧設計淺析
Internet 技術。要實現嵌入式設備的網絡化,需要實現TCP/IP網絡協議棧,但由于Internet上各種通信協議對計算機存儲器、運算速度等的要求比較高,使得嵌入式系統協議
發表于 02-20 14:59
?1750次閱讀
嵌入式系統中實現對USB接口微小變化的測控
隨著臺式機和筆記本電腦串口的消失,USB已成為最常見的外圍設備接口。此外,USB的嵌入式應用正在增加。但是,在嵌入式系統中實現USB接口的開發團隊可以輕松地產生微小的
嵌入式系統中棧的變化
評論