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

函數運行時在內存中是什么樣子?

存儲 存儲軟件
你知道協程的本質是什么嗎?有的同學可能會說是用戶態線程,那么什么是用戶態線程,這是怎么實現的?3. 函數運行起來后在內存中是什么樣子?這幾個問題看似沒什么關聯,但這背后都指向一樣東西,這就是所謂的函數運行時棧,run time stack。接下來我們就好好看看到底什么是函數運行時棧,為什么徹底理解函數運行時棧對程序員來說非常重要。

[[352330]]

在開始本篇的內容前,我們先來思考幾個問題。1. 我們先來看一段簡單的代碼:

  1. void func(int a) { 
  2.   if (a > 100000000) return
  3.    
  4.   int arr[100] = {0}; 
  5.   func(a + 1); 

你知道協程的本質是什么嗎?有的同學可能會說是用戶態線程,那么什么是用戶態線程,這是怎么實現的?3. 函數運行起來后在內存中是什么樣子?這幾個問題看似沒什么關聯,但這背后都指向一樣東西,這就是所謂的函數運行時棧,run time stack。接下來我們就好好看看到底什么是函數運行時棧,為什么徹底理解函數運行時棧對程序員來說非常重要。

從進程、線程到函數調用

汽車在高速上行駛時有很多信息,像速度、位置等等,通過這些信息我們可以直觀的感受汽車的運行時狀態。

同樣的,程序在運行時也有很多信息,像有哪些程序正在運行、這些程序執行到了哪里等等,通過這些信息我們可以直觀的感受系統中程序運行的狀態。

 

其中,我們創造了進程、線程這樣的概念來記錄有哪些程序正在運行,關于進程和線程的概念請參見《看完這篇還不懂進程、線程與線程池你來打我》。進程和線程的運行體現在函數執行上,函數的執行除了函數內部執行的順序執行還有子函數調用的控制轉移以及子函數執行完畢的返回。其中函數內部的順序執行乏善可陳,重點是函數的調用。因此接下來我們的視角將從宏觀的進程和線程拉近到微觀下的函數調用,重點來討論一下函數調用是怎樣實現的。

函數執行的活動軌跡:棧

玩過游戲的同學應該知道,有時你為了完成一項主線任務不得不去打一些支線的任務,支線任務中可能還有支線任務,當一個支線任務完成后退回到前一個支線任務,這是什么意思呢,舉個例子你就明白了。假設主線任務西天取經A依賴支線任務收服孫悟空B和收服豬八戒C,也就是說收服孫悟空B和收服豬八戒C完成后才能繼續主線任務西天取經A;支線任務收服孫悟空B依賴任務拿到緊箍咒D,只有當任務D完成后才能回到任務B;整個任務的依賴關系如圖所示:

現在我們來模擬一下任務完成過程。首先我們來到任務A,執行主線任務:

 

執行任務A的過程中我們發現任務A依賴任務B,這時我們暫停任務A去執行任務B:

執行任務B的時候,我們又發現依賴任務D:

執行任務D的時候我們發現該任務不再依賴任何其它任務,因此C完成后我們可以會退到前一個任務,也就是B:

任務B除了依賴任務C外不再依賴其它任務,這樣任務B完成后就可以回到任務A:

現在我們回到了主線任務A,依賴的任務B執行完成,接下來是任務C:

和任務D一樣,C不依賴任何其它其它任務,任務C完成后就可以再次回到任務A,再之后任務A執行完畢,整個任務執行完成。讓我們來看一下整個任務的活動軌跡:

仔細觀察,實際上你會發現這是一個First In Last Out 的順序,天然適用于棧這種數據結構來處理。再仔細看一下棧頂的軌跡,也就是A、B、D、B、A、C、A,實際上你會發現這里的軌跡就是任務依賴樹的遍歷過程,是不是很神奇,這也是為什么樹這種數據結構的遍歷除了可以用遞歸也可以用棧來實現的原因。

 

A Box

函數調用也是同樣的道理,你把上面的ABCD換成函數ABCD,本質不變。因此,現在我們知道了,使用棧這種結構就可以用來保存函數調用信息。和游戲中的每個任務一樣,當函數在運行時每個函數也要有自己的一個“小盒子”,這個小盒子中保存了函數運行時的各種信息,這些小盒子通過棧這種結構組織起來,這個小盒子就被稱為棧幀,stack frames,也有的稱之為call stack,不管用什么命名方式,總之,就是這里所說的小盒子,這個小盒子就是函數運行起來后占用的內存,這些小盒子構成了我們通常所說的棧區。

控制轉移

我們知道當函數A調用函數B的時候,控制從A轉移到了B,所謂控制其實就是指CPU執行屬于哪個函數的機器指令,CPU從開始執行屬于函數A的指令切換到執行屬于函數B的指令,我們就說控制從函數A轉移到了函數B。控制從函數A轉移到函數B,那么我們需要有這樣兩個信息:

  • 我從哪里來 (返回)
  • 要到去哪里 (跳轉)

是不是很簡單,就好比你出去旅游,你需要知道去哪里,還需要記住回家的路。函數調用也是同樣的道理。當函數A調用函數B時,我們只要知道:

  • 函數A對于的機器指令執行到了哪里 (我從哪里來,返回)
  • 函數B第一條機器指令所在的地址 (要到哪里去,跳轉)

有這兩條信息就足以讓CPU開始執行函數B對應的機器指令,當函數B執行完畢后跳轉回函數A。那么這些信息是怎么獲取并保持的呢?現在我們就可以打開這個小盒子,看看是怎么使用的了。假設函數A調用函數B,如圖所示:

當前,CPU執行函數A的機器指令,該指令的地址為0x400564,接下來CPU將執行下一條機器指令也就是:

  1. call 0x400540 

這條機器指令是什么意思呢?

這條機器指令對應的就是我們在代碼中所寫的函數調用,注意call后有一條機器指令地址,注意觀察上圖你會看到,該地址就是函數B的第一條機器指令,從這條機器指令后CPU將跳轉到函數B。

現在我們已經解決了控制跳轉的“要到哪里去”問題,當函數B執行完畢后怎么跳轉回來呢?

原來,call指令除了給出跳轉地址之外還有這樣一個作用,也就是把call指令的下一條指令的地址,也就是0x40056a push到函數A的棧幀中,如圖所示:

現在,函數A的小盒子變大了一些,因為裝入了返回地址:

 

現在CPU開始執行函數B對應的機器指令,注意觀察,函數B也有一個屬于自己的小盒子(棧幀),可以往里面扔一些必要的信息。

如果函數B中又調用了其它函數呢?道理和函數A調用函數B是一樣的。讓我們來看一下函數B最后一條機器指令ret,這條機器指令的作用是告訴CPU跳轉到函數A保存在棧幀上的返回地址,這樣當函數B執行完畢后就可以跳轉到函數A繼續執行了。至此,我們解決了控制轉移中“我從哪里來”的問題。

 

傳遞參數與獲取返回值

函數調用與返回使得我們可以編寫函數,進行函數調用。但調用函數除了提供函數名稱之外還需要傳遞參數以及獲取返回值,那么這又是怎樣實現的呢?

在x86-64中,多數情況下參數的傳遞與獲取返回值是通過寄存器來實現的。假設函數A調用了函數B,函數A將一些參數寫入相應的寄存器,當CPU執行函數B時就可以從這些寄存器中獲取參數了。同樣的,函數B也可以將返回值寫入寄存器,當函數B執行結束后函數A從該寄存器中就可以讀取到返回值了。我們知道寄存器的數量是有限的,當傳遞的參數個數多于寄存器的數量該怎么辦呢?這時那個屬于函數的小盒子也就是棧幀又能發揮作用了。原來,當參數個數多于寄存器數量時剩下的參數直接放到棧幀中,這樣被調函數就可以從前一個函數的棧幀中獲取到參數了。現在棧幀的樣子又可以進一步豐富了,如圖所示:

從圖中我們可以看到,調用函數B時有部分參數放到了函數A的棧幀中,同時函數A棧幀的頂部依然保存的是返回地址。

 

局部變量

我們知道在函數內部定義的變量被稱為局部變量,這些變量在函數運行時被放在了哪里呢?原來,這些變量同樣可以放在寄存器中,但是當局部變量的數量超過寄存器的時候這些變量就必須放到棧幀中了。因此,我們的棧幀內容又一步豐富了。

細心的同學可能會有這樣的疑問,我們知道寄存器是共享資源可以被所有函數使用,既然可以將函數A的局部變量寫入寄存器,那么當函數A調用函數B時,函數B的局部變量也可以寫到寄存器,這樣的話當函數B執行完畢回到函數A時寄存器的值已經被函數B修改過了,這樣會有問題吧。這樣的確會有問題,因此我們在向寄存器中寫入局部變量之前,一定要先將寄存器中開始的值保存起來,當寄存器使用完畢后再恢復原值就可以了。那么我們要將寄存器中的原始值保存在哪里呢?有的同學可能已經猜到了,沒錯,依然是函數的棧幀中。

最終,我們的小盒子就變成了如圖所示的樣子,當寄存器使用完畢后根據棧幀中保存的初始值恢復其內容就可以了。現在你應該知道函數在運行時到底是什么樣子了吧,以上就是問題3的答案。

 

Big Picture

需要再次強調的一點就是,上述討論的棧幀就位于我們常說的棧區。棧區,屬于進程地址空間的一部分,如圖所示,我們將棧區放大就是圖左邊的樣子。

 

 

關于棧區詳細的講解你可以參考《深入理解操作系統:程序員應如何理解內存》這篇。最后,讓我們回到文章開始的這段簡單代碼:

  1. void func(int a) { 
  2.     if (a > 100000000) return
  3.      
  4.     int arr[100] = {0}; 
  5.     func(a + 1); 
  6.  
  7. void main(){ 
  8.     func(0); 

想一想這段代碼會有什么問題?原來,棧區是有大小限制的,當超過限制后就會出現著名的棧溢出問題,顯然上述代碼會導致這一問題的出現。因此:

不要創建過大的局部變量

函數棧幀,也就是調用層次不能太多

總結

 

本章我們從幾個看似沒什么關聯的問題出發,詳細講解了函數運行時棧是怎么一回事,為什么我們不能創建過多的局部變量。細心的同學會發現第2個問題我們沒有解答,這個問題的講解放到下一篇,也就是協程中講解。希望這篇文章能對大家理解函數運行時棧有所幫助。

本文轉載自微信公眾號「 碼農的荒島求生」,可以通過以下二維碼關注。轉載本文請聯系 碼農的荒島求生公眾號。

 

責任編輯:武曉燕 來源: 碼農的荒島求生
相關推薦

2022-03-15 16:19:13

物聯網物聯網 2.0IoT

2011-10-10 11:04:54

2022-10-10 08:47:49

ITCIO數據

2021-09-11 15:38:23

容器運行鏡像開放

2021-10-29 10:55:07

Go 泛型語言

2024-11-13 13:05:02

Python函數對象

2018-04-11 15:22:58

2021-09-14 16:32:11

物聯網IOT

2022-04-08 09:59:03

物聯網2.0物聯網

2021-02-19 10:14:49

云計算公共云

2021-05-08 13:11:58

物聯網IOT物聯網技術

2018-11-28 14:53:44

物聯網網關物聯網IOT

2021-08-13 08:15:23

JVM 虛擬機Java

2023-07-28 10:42:43

2020-04-09 11:00:20

Java虛擬機對象

2021-05-31 09:26:01

機器學習人工智能計算機

2022-05-30 18:54:12

元宇宙Web3數據量

2015-07-20 15:44:46

Swift框架MJExtension反射

2021-11-29 07:42:44

CSS 技巧CSS 繪圖技巧

2021-10-04 15:46:31

網絡通信5G
點贊
收藏

51CTO技術棧公眾號

91传媒视频在线观看| 久久亚洲精品一区二区| 欧美性猛交xxx乱久交| 日本中文字幕电影在线免费观看| 国产在线播放一区二区三区| 国模吧一区二区| 微拍福利一区二区| 日韩中文一区二区| 色综合久久六月婷婷中文字幕| 一本久久a久久精品vr综合| www.天堂在线| 日韩av中文字幕一区二区| 日韩视频免费看| 最近中文字幕无免费| 色综合视频一区二区三区日韩 | 日本高清www| 中文成人激情娱乐网| 精品久久久国产| 亚洲国产精品女人| 国模吧精品人体gogo| 大尺度一区二区| 国产精品三级美女白浆呻吟 | 2022国产精品| 国产一区二区视频免费| 亚洲视屏一区| 久久成人免费视频| 成熟人妻av无码专区| 欧美爱爱网站| 精品国产一区二区三区忘忧草| 成人中文字幕av| 美女高潮视频在线看| 亚洲视频一二三区| 日韩亚洲欧美精品| 青青草视频在线观看| 国产99久久久久| 91久久国产精品| 中文字幕在线观看免费| 老司机精品视频网站| 91国产美女视频| 国产在线免费视频| 女主播福利一区| 久久亚洲精品中文字幕冲田杏梨| youjizz亚洲女人| 国产一区二区区别| 日韩精品免费观看| aaaaaav| 韩国精品福利一区二区三区| 欧美成人一级视频| www.五月天色| 亚洲一区二区av| 欧美日韩国产精品成人| 亚洲精品视频导航| 久久久久久久性潮| 欧美日韩国产高清一区二区三区| 久久99爱视频| 色综合久久久| 日韩欧美亚洲另类制服综合在线 | 波多野结衣 久久| 国产精品久久久久久模特| 午夜精品一区二区三区在线播放| 国产情侣在线视频| 一本色道久久综合亚洲精品不| 国内精品一区二区三区| 日韩久久精品视频| 久久国产99| 国产精品人成电影| 国产麻豆一精品一男同| 国产乱码精品1区2区3区| 91香蕉电影院| 乱色精品无码一区二区国产盗| 岛国精品在线播放| 精品婷婷色一区二区三区蜜桃| 视频一区二区在线播放| 久久久精品黄色| 亚洲一二三区在线| 18加网站在线| 午夜成人免费电影| 成人午夜激情av| 亚洲精品777| 精品国产乱码久久久久久1区2区 | 禁果av一区二区三区| 在线视频欧美性高潮| 欧美丰满熟妇bbbbbb| 最新成人av网站| 国产精品激情自拍| 国产三级视频在线播放| 99精品桃花视频在线观看| 欧美日韩中文国产一区发布 | 国产精品国产精品国产专区不蜜| 99视频精品全部免费看| 手机在线观看av| 欧美日韩一区二区电影| 日本人妻一区二区三区| 亚洲最大在线| 蜜臀久久99精品久久久无需会员 | 亚洲第一区在线观看| 草草影院第一页| 亚洲国产精品久久久天堂| 国内精品模特av私拍在线观看| 人妻中文字幕一区二区三区| 国产盗摄视频一区二区三区| 免费观看成人高| 成人免费观看视频大全| 一本一道久久a久久精品| 亚洲一区精品视频在线观看| 思热99re视热频这里只精品| 精品激情国产视频| 欧美日韩乱国产| 国产精品影音先锋| 日日骚一区二区网站| av资源在线看片| 欧美人成免费网站| aa一级黄色片| 欧美天天视频| 成人国产精品一区| 国外av在线| 亚洲国产精品久久艾草纯爱| 在线视频观看91| 国产麻豆一区二区三区精品视频| 久久免费国产视频| 国产精品欧美久久久久天天影视| 久久一日本道色综合| 国产免费一区二区视频| 激情久久免费视频| 中文字幕日韩免费视频| 手机在线看片1024| 成人avav影音| 欧美一二三不卡| 91麻豆精品| 中文字幕日韩免费视频| 午夜一区二区三区四区| 久久综合九色综合欧美98| 免费看欧美一级片| 日本综合精品一区| 久久亚洲国产精品| 国产片在线播放| 一区二区中文字幕在线| 天堂网在线免费观看| 国产精品亚洲二区| 欧洲成人免费aa| 在线观看xxx| 精品久久久久久国产| 亚洲婷婷在线观看| 99视频精品| 精品无码久久久久国产| 伊人久久视频| 亚洲欧美一区二区激情| 久久久久在线视频| 国产三级精品三级| 在线观看av日韩| 日本道不卡免费一区| 国产精品视频网址| 95在线视频| 欧美日韩高清在线| 三级av在线免费观看| 国产精品一区二区在线播放 | 亚洲免费综合| 免费日韩av电影| 偷拍视频一区二区三区| 亚洲天堂av电影| 一本一道人人妻人人妻αv| 国产精品福利影院| 日本wwwxx| 最新成人av网站| 欧美精品在线一区| 成人国产在线| 超碰91人人草人人干| 北条麻妃一二三区| 精品久久久香蕉免费精品视频| 色婷婷av777| 蜜臀99久久精品久久久久久软件| a级网站在线观看| 草草视频在线一区二区| 日本成人免费在线| 欧美videos极品另类| 日韩欧美一级二级三级久久久| 日韩欧美大片在线观看| 久久久久久久av麻豆果冻| 一区二区三区 欧美| 真实国产乱子伦精品一区二区三区| 成人xxxxx色| 性欧美videohd高精| 久久精品中文字幕免费mv| 成人午夜免费在线观看| 一本大道av伊人久久综合| 蜜臀av午夜精品久久| 99久久国产综合精品色伊| 岛国毛片在线播放| 影音国产精品| 亚洲激情一区二区三区| 91久久精品无嫩草影院 | 男人天堂av在线播放| 国产精品水嫩水嫩| a级片在线观看视频| 日本美女视频一区二区| 老子影院午夜伦不卡大全| 精品欧美久久| 国产三区精品| 3d动漫一区二区三区在线观看| 91黑丝在线观看| 色综合久久影院| 精品性高朝久久久久久久| 国产喷水福利在线视频| 日本高清免费不卡视频| 久草资源在线视频| 欧美国产日本韩| japanese在线观看| 国产在线不卡一卡二卡三卡四卡| 日韩在线xxx| 狠狠入ady亚洲精品经典电影| 亚欧精品在线| 嫩草国产精品入口| 亚洲尤物视频网| 粉嫩91精品久久久久久久99蜜桃| 97人人模人人爽人人喊中文字| 黄色网址在线免费播放| 亚洲欧洲免费视频| 亚州男人的天堂| 日韩女优视频免费观看| 亚洲最大成人av| 91国模大尺度私拍在线视频| 日本高清www免费视频| 亚洲精品乱码久久久久久久久| 成人黄色短视频| 久久久精品国产免大香伊| 久久久久亚洲无码| 国产91精品精华液一区二区三区| 亚洲一区二区福利视频| 日本麻豆一区二区三区视频| 男女av免费观看| 亚洲人成人一区二区三区| a级片一区二区| 亚洲精品久久| 最近免费观看高清韩国日本大全| 久久影视一区| 亚洲一区不卡在线| 色喇叭免费久久综合| 手机成人在线| 成人毛片免费看| 午夜精品福利一区二区| 精品国产乱码久久久久久果冻传媒 | 日韩 欧美 高清| 三级影片在线观看欧美日韩一区二区 | 亚洲欧美日本一区| 99久久99久久免费精品蜜臀| av av在线| 成人h动漫精品一区二| 国产一级免费片| a亚洲天堂av| 添女人荫蒂视频| 久久亚洲欧美国产精品乐播| 亚洲天堂久久新| 久久精品亚洲国产奇米99| 中文字幕网站在线观看| 国产午夜精品理论片a级大结局| 一道本在线观看| 国产日韩v精品一区二区| 一级片久久久久| 国产精品国产三级国产普通话99| 蜜桃视频成人m3u8| 欧美一区二区福利在线| 国产精品人人爽| 91精品国产91久久综合桃花| www.av黄色| 亚洲成人av在线| 色视频在线观看| 一区二区三区www| 欧美一区二区三区| 欧美人与性动交| 69av成人| 国产精品日韩在线播放| 国产成人免费av一区二区午夜| 成人高清在线观看| 亚洲人成精品久久久| 香蕉久久夜色| 欧美国产免费| 91传媒久久久| 麻豆国产欧美日韩综合精品二区| 日本少妇一区二区三区| 972aa.com艺术欧美| 纪美影视在线观看电视版使用方法| 亚洲欧美一区二区三区极速播放 | 国产精品久久久久久久久影视| 亚洲美女色播| 精品国产91亚洲一区二区三区www| 久久av免费看| 国产日韩欧美大片| 亚洲自拍另类| 亚洲一区二区偷拍| 91亚洲永久精品| 亚洲人与黑人屁股眼交| 亚洲.国产.中文慕字在线| 性色av一区二区三区四区| 欧美一级免费大片| 免费在线一级视频| 欧美成人激情图片网| 高清不卡av| 99re热精品| 成人高清电影网站| 99久久免费观看| 麻豆精品久久精品色综合| 天天插天天射天天干| √…a在线天堂一区| 日本在线播放视频| 欧美一级高清大全免费观看| 黄色在线观看网| 久久久久久久久久久免费精品| av成人在线观看| 精品婷婷色一区二区三区蜜桃| 911精品美国片911久久久| 韩国日本在线视频| 丁香五精品蜜臀久久久久99网站 | 三级无遮挡在线观看| 久久国产精彩视频| 日韩大陆av| 精品中文字幕人| 欧美88av| 国产精品嫩草影院8vv8| 国产偷国产偷精品高清尤物| 日本熟伦人妇xxxx| 欧美一级黄色录像| 青青青青在线| 国产精品爽爽爽爽爽爽在线观看| 一区二区三区在线资源| 久久最新免费视频| 麻豆精品一区二区综合av| 91中文字幕永久在线| 婷婷成人激情在线网| www.国产.com| 久久成年人视频| 国产精品igao视频网网址不卡日韩 | www.xxx亚洲| 26uuu成人网一区二区三区| 免费毛片一区二区三区| 欧美变态凌虐bdsm| a篇片在线观看网站| 成人av番号网| 偷偷www综合久久久久久久| 欧美三级理论片| 欧美国产欧美亚州国产日韩mv天天看完整| 日本三级小视频| 亚洲精品国产精品国自产在线| 超碰97免费在线| 国产一区二区不卡视频| 一区二区黄色| 国产精品无码一区二区三| 欧美日韩激情美女| 日本护士...精品国| 日韩美女毛茸茸| 精品国产一级毛片| 色乱码一区二区三区在线| 中日韩av电影| 92久久精品一区二区| 插插插亚洲综合网| 亚洲国产中文在线| 国产av人人夜夜澡人人爽麻豆| 成人av网站免费| 日韩精品在线免费视频| 亚洲香蕉成人av网站在线观看| 欧美日韩视频免费观看| 亚洲自拍偷拍二区| 国产剧情一区在线| 久久中文字幕无码| 日韩精品视频在线| 高清电影一区| 日本福利视频导航| 国产a视频精品免费观看| 亚洲午夜18毛片在线看| 亚洲午夜激情免费视频| 日本久久二区| 欧美午夜小视频| 国产婷婷色一区二区三区四区| 在线观看日韩一区二区| 久久99热精品| 免费av一区| 高潮一区二区三区| 亚洲午夜久久久久| 欧美日韩免费做爰大片| 成人有码视频在线播放| 亚洲高清不卡| 99精品全国免费观看| 日韩一区二区视频在线观看| 日本а中文在线天堂| 亚洲欧美影院| 成人免费高清在线| 日韩综合在线观看| 欧美国产日韩二区| 精品产国自在拍| 无码人妻aⅴ一区二区三区玉蒲团| 精品免费在线视频| 天天影视久久综合| 国产一区二区中文字幕免费看| 美女性感视频久久| 日韩成人免费观看| 俺去亚洲欧洲欧美日韩| 西野翔中文久久精品字幕| 91在线第一页| 色激情天天射综合网| 青春草在线视频| 亚洲国产欧洲综合997久久|