精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

函數調用時棧是如何變化的?

系統 Linux
大家都知道函數調用是通過棧來實現的,而且知道在棧中存放著該函數的局部變量。但是對于棧的實現細節可能不一定清楚。本文將介紹一下在Linux平臺下函數棧是如何實現的。

 

大家都知道函數調用是通過棧來實現的,而且知道在棧中存放著該函數的局部變量。但是對于棧的實現細節可能不一定清楚。本文將介紹一下在Linux平臺下函數棧是如何實現的。

棧幀的結構

函數在調用的時候都是在棧空間上開辟一段空間以供函數使用,所以,我們先來了解一下通用棧幀的結構。

如圖所示,棧是由高地址向地地址的方向生長的,而且棧有其棧頂和棧底,入棧出棧的地方就叫做棧頂。

在x86系統的CPU中,rsp是棧指針寄存器,這個寄存器中存儲著棧頂的地址。rbp中存儲著棧底的地址。函數棧空間主要是由這兩個寄存器來確定的。

當程序運行時,棧指針rsp可以移動,棧指針和幀指針rbp一次只能存儲一個地址,所以,任何時候,這一對指針指向的是同一個函數的棧幀結構。

而幀指針rbp是不移動的,訪問棧中的元素可以用-4(%rbp)或者8(%rbp)訪問%rbp指針下面或者上面的元素。

在明白了這些之后,下面我們來看一個具體的例子: 

  1. #include <stdio.h>  
  2. int sum (int a,int b)  
  3.  
  4.  int c = a + b;  
  5.  return c;  
  6.  
  7. int main()  
  8.  
  9.  int x = 5,y = 10,z = 0 
  10.  z = sum(x,y);  
  11.  printf("%d\r\n",z);  
  12.  return 0;  

反匯編如下,下面我們就對照匯編代碼一步一步分析下函數調用過程中棧的變化。 

  1. 0000000000000000 <sum> 
  2.    0: 55                    push   %rbp   
  3.    1: 48 89 e5              mov    %rsp,%rbp  
  4.    4: 89 7d ec              mov    %edi,-0x14(%rbp) # 參數傳遞  
  5.    7: 89 75 e8              mov    %esi,-0x18(%rbp) # 參數傳遞  
  6.    a: 8b 55 ec              mov    -0x14(%rbp),%edx  
  7.    d: 8b 45 e8              mov    -0x18(%rbp),%eax  
  8.   10: 01 d0                 add    %edx,%eax   
  9.   12: 89 45 fc              mov    %eax,-0x4(%rbp) # 局部變量  
  10.   15: 8b 45 fc              mov    -0x4(%rbp),%eax # 存儲結果  
  11.   18: 5d                    pop    %rbp  
  12.   19: c3                    retq     
  13. 000000000000001a <main> 
  14.   1a: 55                    push   %rbp # 保存%rbp。rbp,棧底的地址  
  15.   1b: 48 89 e5              mov    %rsp,%rbp # 設置新的棧指針。rsp 棧指針,指向棧頂的地址  
  16.   1e: 48 83 ec 10           sub    $0x10,%rsp # 分配 16字節棧空間。%rsp = %rsp-16  
  17.   22: c7 45 f4 05 00 00 00  movl   $0x5,-0xc(%rbp) # 賦值  
  18.   29: c7 45 f8 0a 00 00 00  movl   $0xa,-0x8(%rbp) # 賦值  
  19.   30: c7 45 fc 00 00 00 00  movl   $0x0,-0x4(%rbp) # 賦值  
  20.   37: 8b 55 f8              mov    -0x8(%rbp),%edx    
  21.   3a: 8b 45 f4              mov    -0xc(%rbp),%eax   
  22.   3d: 89 d6                 mov    %edx,%esi # 參數傳遞 ,從右向左  
  23.   3f: 89 c7                 mov    %eax,%edi # 參數傳遞  
  24.   41: e8 00 00 00 00        callq  46 <main+0x2c> # 調用sum 
  25.   46: 89 45 fc              mov    %eax,-0x4(%rbp)   
  26.   49: 8b 45 fc              mov    -0x4(%rbp),%eax # 存儲計算結果  
  27.   4c: 89 c6                 mov    %eax,%esi  
  28.   4e: 48 8d 3d 00 00 00 00  lea    0x0(%rip),%rdi        # 55 <main+0x3b>  
  29.   55: b8 00 00 00 00        mov    $0x0,%eax  
  30.   5a: e8 00 00 00 00        callq  5f <main+0x45>  
  31.   5f: b8 00 00 00 00        mov    $0x0,%eax   
  32.   64: c9                    leaveq   
  33.   65: c3                    retq    

函數調用前

在函數被調用之前,調用者會為調用函數做準備。首先,函數棧上開辟了16字節的空間,存儲定義的3個int型變量,建立了main函數的棧。

接著,會給三個變量進行賦值。

以下4行代碼是進行參數傳遞。我們可以看到是函數參數是倒序傳入的:先傳入第N個參數,再傳入第N-1個參數(CDECL約定)。 

  1. mov    -0x8(%rbp),%edx    
  2. mov    -0xc(%rbp),%eax   
  3. mov    %edx,%esi # 參數傳遞 ,從右向左  
  4. mov    %eax,%edi # 參數傳遞 

最后,會執行到call指令處,調用sum函數。 

  1. callq  46 <main+0x2c> # 調用sum 

CALL指令內部其實還暗含了一個將返回地址(即CALL指令下一條指令的地址)壓棧的動作(由硬件完成)。

具體來說,call指令執行時,先把下一條指令的地址入棧,再跳轉到對應函數執行的起始處。

函數調用時

進入sum函數后,我們看到函數的前兩行: 

  1. push   %rbp   
  2. mov    %rsp,%rbp 

這兩條匯編指令的含義是:首先將rbp寄存器入棧,然后將棧頂指針rsp賦值給rbp。

“mov rbp rsp”這條指令表面上看是用rsp覆蓋rbp原來的值,其實不然。

因為給rbp賦值之前,原rbp值已經被壓棧(位于棧頂),而新的rbp又恰恰指向棧頂。此時rbp寄存器就已經處于一個非常重要的地位。

該寄存器中存儲著棧中的一個地址(原rbp入棧后的棧頂),從該地址為基準,向上(棧底方向)能獲取返回地址、參數值,向下(棧頂方向)能獲取函數局部變量值,而該地址處又存儲著上一層函數調用時的rbp值。

一般而言,%rbp+4處為返回地址,%rbp+8處為第一個參數值(最后一個入棧的參數值,此處假設其占用4字節內存),%rbp-4處為第一個局部變量,%rbp處為上一層rbp值。

由于rbp中的地址處總是“上一層函數調用時的rbp值”,而在每一層函數調用中,都能通過當時的%rbp值“向上(棧底方向)”能獲取返回地址、參數值,“向下(棧頂方向)”能獲取函數局部變量值。

緊接著執行的四條指令。 

  1. mov    %edi,-0x14(%rbp) # 參數傳遞  
  2. mov    %esi,-0x18(%rbp) # 參數傳遞  
  3. mov    -0x14(%rbp),%edx  
  4. mov    -0x18(%rbp),%eax  
  5. add    %edx,%eax  
  6. mov    %eax,-0x4(%rbp) 

上述指令通過rbp加偏移量的方式將main傳遞給sum的兩個參數保存在當前棧幀的合適位置,然后又取出來放入寄存器,看著有點兒多此一舉,這是因為在編譯時未給gcc指定優化級別,而gcc編譯程序時,默認不做任何優化,所以看起來比較啰嗦。

需要說明的是,sum的兩個參數和返回值都是int,在內存中只占4個字節,而圖中每個棧內存單元按8字節地址邊界進行了對齊,所以才是下圖中這個樣子。

再來看緊接著的三條指令。 

  1. add    %edx,%eax   
  2. mov    %eax,-0x4(%rbp) # 局部變量  
  3. mov    -0x4(%rbp),%eax # 存儲結果 

上述第一條指令負責執行加法運算并將并將結果存入eax中,第二條指令將eax中的值存入局部變量c所在的內存,第三條指令將局部變量c的值讀取到eax中,可以看到,局部變量c被編譯器安排到了%rbp -0x4這個地址對應的內存中。

接下來繼續執行 

  1. pop %rbp  
  2. retq 

這兩條指令的功能相當于下面的指令: 

  1. mov %rbp,%rsp  
  2. pop %rbp  
  3. pop %rip 

即在操作上面兩條指令的時候,首先把rsp賦值,它的值是存儲調用函數rbp的值的地址,所以可以通過出棧操作,來給rbp賦值,來找回調用函數的rbp。

通過棧的結構,可以知道,rbp上面就是調用函數調用被調用函數的下一條指令的執行地址,所以需要賦值給rip,來找回調用函數里的指令執行地址。

整個函數跳轉回main的時候,他的rsp,rbp都會變回原來的main函數的棧指針,C語言程序就是用這種方式來確保函數的調用之后,還能繼續執行原來的程序。

函數調用后

函數最后返回的時候,繼續執行下面這條指令: 

  1. mov    %eax,-0x4(%rbp)  # 把sum函數的返回值賦給變量z 

上述指令將eax中的結果放入rbp  -0x4所指的內存中,這里也是main的局部變量z所在位置。

再往后的指令如下: 

  1. mov    %eax,-0x4(%rbp)   
  2. mov    -0x4(%rbp),%eax # 計算結果  
  3. mov    %eax,%esi  
  4. mov    %eax,%esi  
  5. lea    0x0(%rip),%rdi  
  6. mov    $0x0,%eax  
  7. callq  5f <main+0x45> 

上述指令首先為printf準備參數,然后調用printf,具體過程和調用sum的過程相似,讓CPU直接執行到main倒數第二條leave指令處。 

  1. mov    $0x0,%eax  

指令作用是將main返回值0放到寄存器eax,等main返回后調用main可拿到這個值。

執行leave指令相當于執行如下兩條指令: 

  1. mov %rbp, %rsp  
  2. pop %rbp 

leave指令首先將rbp的值復制給rsp,rsp就指向rbp所指的棧單元。之后leave指令將該棧單元的值pop給rbp,如此,rsp和rbp就恢復成剛進入main時的狀態。 

 

責任編輯:龐桂玉 來源: C語言與C++編程
相關推薦

2023-12-01 14:57:22

TCP連接

2020-11-17 14:28:56

數據中心

2014-11-10 10:52:33

Go語言

2022-05-19 15:08:43

技術函數調用棧Linux

2010-07-28 15:29:18

Flex函數

2010-01-28 13:35:41

調用C++函數

2022-03-22 10:51:53

數據棧數據

2023-11-29 16:29:09

線程java

2019-07-23 15:04:54

JavaScript調用棧事件循環

2020-07-31 18:33:56

C++編程語言

2019-08-28 14:21:39

C++C接口代碼

2021-04-01 11:28:44

C++ LinuxWindows

2018-11-05 14:53:14

Go函數代碼

2010-07-07 10:25:00

SQL Server索

2010-09-08 15:24:28

TCP IP協議棧

2023-11-09 23:31:02

C++函數調用

2024-09-05 17:45:33

Vue函數

2022-09-27 08:01:48

遞歸函數GScript

2023-06-15 14:10:00

kubeletCNI插件

2022-04-02 07:52:47

DubboRPC調用動態代理
點贊
收藏

51CTO技術棧公眾號

亚洲乱码日产精品bd在线观看| 欧美国产一区二区三区| 搡女人真爽免费午夜网站| 337p日本欧洲亚洲大胆鲁鲁| 人妻无码一区二区三区四区| a级一a一级在线观看| 久热在线观看视频| 在线观看日韩羞羞视频| 另类小说一区二区三区| 亚洲成a人片在线不卡一二三区| 91精品中国老女人| 97超碰人人爱| 免费国产a级片| 欧美午夜不卡影院在线观看完整版免费| 国产伦精品一区二区三区视频青涩| 特级特黄刘亦菲aaa级| 欧美成人一区二区三区四区| 欧美日韩一二三四| 欧美高清一级片在线| 91黄色在线看| 香蕉视频网站在线观看| 精品国产一区二区三区久久久樱花 | 极品中文字幕一区| 成人丝袜高跟foot| 国产精品九色蝌蚪自拍| 国产欧洲精品视频| 国产91av视频| 97精品在线| 一级中文字幕一区二区| 欧美激情一区二区三区在线视频 | 国产玉足榨精视频在线观看| 国产成都精品91一区二区三| 国产精品人成电影在线观看| 日韩三级视频在线| 欧美一区二区三区免费看| 夜夜嗨av一区二区三区四区| 婷婷五月精品中文字幕| 精品亚洲美女网站| 一区二区三区四区五区视频在线观看 | 免费看日产一区二区三区| 色综合久久88色综合天天免费| 成人高清dvd| 国产精品视频中文字幕| 蜜桃在线一区二区三区精品| 亚洲精品卡一卡二| 美日韩中文字幕| 3d成人h动漫网站入口| 爆乳熟妇一区二区三区霸乳| 黄色在线网站噜噜噜| 一区二区三区四区激情| gogogo免费高清日本写真| yiren22亚洲综合伊人22| 91麻豆文化传媒在线观看| 国产精品久久久久久久久婷婷| 国产精品久久久久久免费| 蜜桃视频一区二区三区在线观看| 国产成人精品优优av| 天天操天天干视频| 亚洲免费网站| 欧美亚洲成人网| 免费黄色网址在线| 国产亚洲毛片| 热re91久久精品国99热蜜臀| 在线观看日韩中文字幕| 亚洲一区黄色| 欧美88av| 亚洲人成毛片在线播放| 久久av无码精品人妻系列试探| 欧美男男freegayvideosroom| 亚洲国产99精品国自产| 玖玖爱在线精品视频| 亚洲精品进入| 国产一区二区三区视频在线观看| 无码一区二区三区在线| 日韩欧美不卡| 成年人精品视频| 国产性70yerg老太| aa亚洲婷婷| 国产91色在线免费| 中文精品久久久久人妻不卡| 精品无人码麻豆乱码1区2区 | 一区二区三区国产精品| 欧美综合激情| 国产精品久久久久久久久婷婷| 日韩精品在线免费视频| 久久激情综合| 国产一区视频在线| 亚洲h视频在线观看| www.欧美日韩| 亚洲高清视频在线观看| 快射av在线播放一区| 亚洲自拍偷拍欧美| 日本一极黄色片| 亚洲狼人在线| 日韩电影中文字幕av| 摸摸摸bbb毛毛毛片| 亚洲乱码精品| 欧美自拍大量在线观看| 国产一区二区网站| 99精品视频在线免费观看| 图片区小说区区亚洲五月| 国产在线高清视频| 欧美午夜影院在线视频| 99精品999| 亚洲精品aaaaa| 欧美成年人视频| 亚洲欧美另类在线视频| 国产乱对白刺激视频不卡| 欧美极品jizzhd欧美| 影音先锋在线播放| 色屁屁一区二区| 久久久久亚洲av无码网站| 欧美日韩在线二区| 久久久久久18| 97人妻人人澡人人爽人人精品| 成人激情文学综合网| 中文精品视频一区二区在线观看| 爱啪啪综合导航| 欧美一区二区三区影视| 青青草视频成人| 欧美精品一卡| 国产日韩欧美影视| 精品久久久久一区二区三区| 亚洲国产一区二区视频| 久久久精品高清| 国产伦精品一区二区三区千人斩 | 美女视频免费一区| 国产精品日韩高清| 黄视频网站在线看| 欧亚洲嫩模精品一区三区| 少妇被狂c下部羞羞漫画| 久久一区二区三区喷水| 青青草成人在线| 你懂的网站在线| 亚洲精品一二三| 国产又黄又猛又粗又爽的视频| 狼人精品一区二区三区在线| 欧美国产日本高清在线 | 在线天堂资源www在线污| 日韩美女天天操| 三级黄色录像视频| 久久亚洲不卡| 欧美精品一区在线| 日本乱码一区二区三区不卡| 亚洲第一av网| 国产大片中文字幕| 丁香桃色午夜亚洲一区二区三区| 免费观看国产视频在线| 日韩色性视频| xxav国产精品美女主播| 在线观看亚洲一区二区| 欧美国产乱子伦| 亚洲三级视频网站| 国产一区二区精品久| 日本乱人伦a精品| 日本成人一区| 欧美性猛交xxxx乱大交3| 狠狠人妻久久久久久综合蜜桃| 亚洲国产婷婷| 久久99精品久久久久久秒播放器| 成人影院在线视频| 日韩精品视频免费专区在线播放| 日本视频免费在线| 99视频超级精品| 大陆极品少妇内射aaaaa| 日韩av不卡一区| 日本国产高清不卡| 国产午夜在线观看| 欧美日韩免费不卡视频一区二区三区| 欧美性生交大片| 国产揄拍国内精品对白| 国产911在线观看| 在线观看免费观看在线| 天天做夜夜做人人爱精品 | 狠狠色丁香婷综合久久| 法国空姐在线观看免费| 一区二区精彩视频| 97色伦亚洲国产| 久久精品色图| 欧美日韩国产综合一区二区 | 一区二区在线| 99精彩视频在线观看免费| 国语对白在线刺激| 日韩激情在线视频| 在线观看毛片网站| 亚洲午夜久久久久中文字幕久| 国产高潮视频在线观看| 老鸭窝毛片一区二区三区| 丝袜足脚交91精品| 视频一区日韩| 日韩av成人在线| 免费av毛片在线看| 精品国产91久久久久久久妲己| 在线观看日韩中文字幕| 国产精品国产三级国产三级人妇| 少妇丰满尤物大尺度写真| 国产农村妇女毛片精品久久莱园子| 日韩精品久久久免费观看| 色综合.com| 91国内在线视频| 伊人免费在线| 精品国产1区2区3区| 日韩xxx视频| 五月婷婷久久丁香| 波兰性xxxxx极品hd| gogogo免费视频观看亚洲一| 中文字幕国产传媒| 亚洲国产电影| 伊人天天久久大香线蕉av色| 韩国女主播一区二区三区| 国产精品羞羞答答| 日本а中文在线天堂| 超碰日本道色综合久久综合| 国产一级免费在线观看| 精品久久久久久久久久久久久久久 | 黑人精品xxx一区一二区| 国产免费美女视频| 久久米奇亚洲| 欧美视频在线不卡| 亚洲一区欧美在线| 亚洲美女一区二区三区| 国产av自拍一区| 丁香网亚洲国际| 午夜久久福利视频| 久久久国产精品一区二区中文| 国产午夜精品视频一区二区三区| 精品一区二区三区在线| 久久精品国产精品青草色艺| 久久国产精品免费一区二区三区| 国产精品18久久久久久首页狼 | 少妇人妻偷人精品一区二区| 欧美高清精品3d| 精品一区二区无码| 欧美日韩视频免费播放| 妺妺窝人体色www婷婷| 亚洲欧洲一区二区在线播放| 欧美大波大乳巨大乳| 97精品久久久午夜一区二区三区| 成年人看片网站| 国产一区在线看| 国产亚洲视频一区| 男女男精品视频| 国产一二三四在线视频| 日韩精品高清不卡| 久草福利视频在线| 久久青草久久| 日本成人在线免费视频| 久久成人精品| 国产精品亚洲αv天堂无码| 一区二区日韩免费看| 国产伦精品一区二区三区四区视频_| 中文字幕日韩一区二区不卡| 热这里只有精品| 亚洲一区二区| 日韩成人午夜影院| 1000精品久久久久久久久| 国产大片一区二区三区| 日本不卡视频一二三区| 国产成人精品视频ⅴa片软件竹菊| 一区二区日韩免费看| 男女视频网站在线观看| 亚洲精品九九| 欧美成人xxxxx| 久久裸体视频| 久久久久国产一区| 久久国产福利国产秒拍| 成年人三级黄色片| 国产在线精品一区二区| 欧美一级免费在线| 国产91丝袜在线播放九色| 国产精品一区二区无码对白| www.色综合.com| 国产精久久一区二区三区| 国产精品色呦呦| 九九热最新地址| 亚洲国产成人porn| 台湾佬中文在线| 欧美日韩精品一区二区在线播放| aaaa一级片| 日韩电影中文字幕一区| 免费人成在线观看网站| 精品国产一区久久久| 久操av在线| 国产成人亚洲综合青青| 电影一区中文字幕| 欧美一级播放| 欧美一区二区三区爽大粗免费| 免费视频一区| 午夜剧场在线免费观看| 成人18视频在线播放| 成人小视频免费看| 亚洲小说欧美激情另类| 高潮毛片又色又爽免费 | 国产欧美精品国产国产专区 | 精品福利视频导航| 在线观看xxxx| 亚洲精品456在线播放狼人| av成人手机在线| 国模精品视频一区二区三区| 日本一区二区三区视频在线| 国产伦精品一区二区三区四区视频 | 日韩av不卡在线观看| 久久久久99人妻一区二区三区| 久久精品人人做| 久久精品国产亚洲AV无码男同| 欧美自拍丝袜亚洲| 黄色一级大片在线免费看国产一 | 亚洲av成人无码网天堂| 日韩av中文字幕在线免费观看| 亚洲AV成人无码一二三区在线| 一区三区二区视频| av在线免费网址| 精品在线视频观看| 手机在线观看免费av| 精品视频在线看| www.午夜激情| 精品国产三级a在线观看| 五月婷婷六月丁香| 精品国产自在精品国产浪潮| 免费高潮视频95在线观看网站| 国产精品日韩在线观看| av日韩在线播放| 午夜欧美性电影| 一区二区日韩免费看| 在线播放免费视频| 91原创在线视频| 欧美特级一级片| 黄色成人av在线| 一区二区美女视频| 亚洲色图美腿丝袜| 国产乱视频在线观看| 久久全球大尺度高清视频| 四虎影视国产精品| 久久综合久久久| 欧美日韩一区自拍| 一级黄色免费毛片| 国产精品美女久久久久久久久 | 又色又爽又黄无遮挡的免费视频| 亚洲女人被黑人巨大进入al| 女囚岛在线观看| 成人有码在线播放| 亚洲h色精品| 爱情岛论坛vip永久入口| 国产丝袜美腿一区二区三区| 久久中文字幕无码| 欧美一级在线观看| 黄av在线播放| 成人午夜小视频| 精品日韩一区| 日本成人在线免费视频| 91片黄在线观看| 久久青青草原亚洲av无码麻豆| 亚洲激情国产精品| 深夜福利视频一区二区| 国产视频一区二区不卡| 伊人影院久久| 三级电影在线看| 性做久久久久久免费观看欧美| 亚洲精品久久久久久久久久久久久久| 免费91麻豆精品国产自产在线观看| 人人视频精品| 亚洲精品视频一区二区三区| 久久精品一区二区国产| 亚洲天堂av中文字幕| 欧日韩精品视频| 黄色片在线看| 国产精品久久久久久久久久ktv| 伊人成综合网yiren22| 天天色综合天天色| 国产精品久久久一本精品| 国产男女裸体做爰爽爽| 美日韩精品免费观看视频| 亚洲精品不卡在线观看| 久久国产精品网| 99久久伊人精品| 国产一级精品视频| 伊人久久久久久久久久久久久 | 成人激情综合网| 伊人久久大香线蕉综合四虎小说 | 免费欧美日韩国产三级电影| 亚洲国产日韩一区无码精品久久久| 欧美日韩高清一区二区| а√天堂8资源在线官网| 亚洲一区二区高清| 一区二区免费av| 亚洲欧美激情在线| 日韩专区一区二区| 欧美在线视频一区二区| 精品亚洲自拍| 男人添女人下面免费视频| 亚洲另类一区二区| 青青草在线免费视频| 国产欧美日韩亚洲精品| 综合久久十次| 中文字幕乱视频| 日韩欧美主播在线| av在线播放国产| 快播亚洲色图| 成人免费高清在线| www.亚洲激情|