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

函數調用中堆棧的個人理解

移動開發 開發
這是我的第一篇博客,由于公司項目需要,將暫時告別C語言一段時間。所以在此記錄一下自己之前學習C語言的一些心得體會,希望可以分享給大家,也可以記錄下自己學習過程中遇到的問題以及存在的疑惑。

這是我的第一篇博客,由于公司項目需要,將暫時告別C語言一段時間。所以在此記錄一下自己之前學習C語言的一些心得體會,希望可以分享給大家,也可以記錄下自己學習過程中遇到的問題以及存在的疑惑(其實就是自己學習過程中不解的地方)。好了,廢話不多說,開始微博內容了,O(∩_∩)O哈哈~

      接下來將通過下面幾個問題解析函數調用中對堆棧理解:

  • 函數調用過程中堆棧在內存中存放的結構如何?
  • 匯編語言中call,ret,leave等具體操作時如何?
  • linux中任務的堆棧,數據存放是如何?

      1. 函數調用過程中堆棧在內存中存放的結構如何?

      計算機,嵌入式設備,智能設備等其實都是有軟件和硬件兩部分組成,具體實現也許復雜,但整體的結構也就如此。軟件運行在硬件上,告訴硬件該干什么。操作系統軟件是在啟動過程中經過BIOS,bootloarder等(如果有這些過程的話)從磁盤加載到內存中,而自定義軟件則是編寫存放到磁盤中,只有通過加載才會到內存中運行。

      首先我們來看一下什么是堆、棧還有堆棧,我們經常說堆棧其實它是等同于棧的概念。

      可以通俗意義上這樣理解堆,堆是一段非常大的內存空間,供不同的程序員從其中取出一段供自己使用,使用之后要由程序員自己釋放,如果不釋放的話,這部分存儲空間將不能被其他程序使用。堆的存儲空間是不連續的,因為會因為不同時間,不同大小的堆空間的申請導致其不連續性。堆的生長是從低地址向高地址增長的。

      對棧的理解是,棧是一段存儲空間,供系統或者操作系統使用,對程序員來說一般是不可見的,除非從一開始由程序員自己通過匯編等自己構建棧,棧會由系統管理單元自己申請釋放。棧是從高地址向低地址生長的,既棧底在高地址,棧頂低地址。

      其次我們看一下應用程序的加載,應用程序被加載進內存后,由操作系統為其分配堆棧,程序的入口函數會是main函數。不過main函數也不是第一個被調用的函數,我們通過簡單的例子講解。

復制代碼
#include <stdio.h>
#include <string.h>

int function(int arg)
{
    return arg;
}
int main(void)
{
    int i = 10;
    int j;
    j = function(i);
    printf("%d\n",j);
    return 0;
}
復制代碼

用gcc -S main.c 生成匯編文件main.s, 其中function的匯編代碼如下:

復制代碼
function:
.LFB0:
    .cfi_startproc
    pushq    %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    %edi, -4(%rbp)
    movl    -4(%rbp), %eax
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
復制代碼

看以看到當函數被調用時,首先會把調用函數的棧底壓棧到自己函數的棧中(pushq %rbp),然后將原來函數棧頂rsp作為當前函數的棧底(movq %rsp, %rbp)。函數運行完成時,會將壓入棧中的rbp重新出棧到rbp中(popq %rbp)。當前function匯編函數沒有顯示出棧頂的變化(rsp的變化),我們可以通過main函數來看棧頂的變化,匯編代碼如下:

復制代碼
main:
.LFB1:
    .cfi_startproc
    pushq    %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    subq    $16, %rsp
    movl    $10, -4(%rbp)
    movl    -4(%rbp), %eax
    movl    %eax, %edi
    call    function
    movl    %eax, -8(%rbp)
    movl    -8(%rbp), %eax
    movl    %eax, %esi
    movl    $.LC0, %edi
    movl    $0, %eax
    call    printf
    movl    $0, %eax
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
復制代碼

從上面的匯編代碼可以看到首先也是壓棧和設置新棧底的過程,從此可以看出main函數也是被調用的函數,而不是第一個調用函數。代碼中的黃色部分是當前棧頂變化,從使用的subq可以知道,棧頂的地址要小于棧底的地址,所以棧是從高地址向低地址生長。

      接下來可能有點繞,慢慢讀,將用語言描述函數調用過程,調用函數會將被調用函數的實參從右往左的順序壓入調用函數的棧中,通過call指令調用被調用函數,首先將return address(也就是call指令的后一條指令的地址)壓入調用函數棧中,這時rsp寄存器中存儲的地址是存放return address內存地址的下一地址值,這時調用函數的棧結構形成,然后就會進入被調用函數的作用域中。被調用函數首先將調用函數的rbp壓入被調用函數棧中(其實這個地址就是rsp寄存器中存儲的地址),接下來將會將這個地址作為被調用函數的rbp地址,才會有movq %rsp, %rbp指令設置被調用函數的棧底。如上所描述的構成了函數調用的堆棧結構如下圖所示。

 

 

此圖來自http://www.cnblogs.com/taek/archive/2012/02/05/2338877.html,此圖中MOV EBP,ESP與本文的movq指令操作不同。

     2. 匯編語言中call,ret,leave等具體操作時如何?

  push:將數據壓入棧中,具體操作是rsp先減,然后將數據壓入sp所指的內存地址中。rsp寄存器總是指向棧頂,但不是空單元。

  pop:將數據從棧中彈出,然后rsp加操作,確保rsp寄存器指向棧頂,不是空單元。

  call:將下一條指令的地址壓入當前調用函數的棧中(將PC指令壓入棧中,因為在從內存中取出call指令時,PC指令已經自動增加),然后改變PC指令的為call的function的地址,程序指針跳轉到新function。

  ret:當指令指到ret指令行時,說明一個函數已經結束了,這時候rsp已經從被調用函數的棧指到了調用函數構建的返回地址位置。ret是將rsp所指棧頂地址中的內容賦值給PC,接下來將執行call function的下一條指令。

  leave:相當于mov %esp, %ebp, pop ebp。頭一條指令其實是把ebp所指的被調用函數的棧底作為新的棧頂,pop指令時相當于把被調用函數的棧底彈出,rsp指向返回地址。

  int:通過其后加中斷號,實現軟件引發中斷,linux操作系統中系統調用多有此實現,其他實時操作系統中在操作系統移植時,會有tick心臟函數也有此實現。

  其他的匯編指令在此就不多講了,因為匯編指令眾多,硬件cpu寄存器也因硬件不同而不同,此節就講了函數構建進入和離開函數時用到的幾個匯編指令,這幾條指令和棧變化有關。自己構建匯編函數,或者是在讀linux操作系統的系統調用時會對其理解有幫助。硬件寄存器中rsp,和rbp用于指示棧頂和棧底。

      3. linux中任務的堆棧,數據存放是如何?

      linux的任務堆棧分為兩種:內核態堆棧和用戶態堆棧。接下來簡單介紹一下這兩個堆棧,如果以后有機會將詳細介紹這兩個堆棧。

1. 內核態堆棧

      linux操作系統分為內核態和用戶態。用戶態代碼訪問代碼和數據收到諸多限制,用戶態主要是為程序員編寫程序使用,處于用戶態的代碼不可以隨便訪問linux內核態的數據,這主要就是設置用戶態的權限,安全考慮。但是用戶態可以通過系統調用接口,中斷,異常等訪問指定內核態的內容。內核態主要是用于操作系統內核運行以及管理,可以無限制的訪問內存地址和數據,權限比較大。

      linux操作系統的進程是動態的,有生命周期,進程的運行和普通的程序運行一樣,需要堆棧的幫助,如果在內核存儲區域內為其提前分配堆棧的話,既浪費內核內存(任務地址大約3G的空間),也不能靈活的構建任務,所以linux操作系統在創建新的任務時,為其分配了8k的存儲區域用于存放進程內核態的堆棧和線程描述符。線程描述符位于分配的存儲區域的低地址區域,大小固定,而內核態堆棧則從存儲區域的高地址開始向低地址延伸。如果之前版本為內核態堆棧和線程描述符分配4k的存儲空間時,則需要為中斷和異常分配額外的棧供其使用,防止任務堆棧溢出。

 

2. 用戶態堆棧

      對于32位的linux操作系統,每個任務都會有4G的尋址空間,其中0-3G為用戶尋址空間,3G-4G為內核尋址空間。每個任務的創建都會有0-3G的用戶尋址空間,但是3G-4G的內核尋址空間是屬于所有任務共享的。這些地址都屬于線性地址,需要通過地址映射轉換成物理地址。為了實現每個任務在訪問0-3G的用戶空間時不至于混淆地址,每個任務的內存管理單元都會有一個屬于自身的頁目錄pgd,在任務創建之初會創建新的pgd,任務會通過地址映射為0-3G空間映射物理地址。用戶態的堆棧就在這0-3G的用戶尋址空間中分配,和之前的main函數以及function函數構建堆棧一樣,但是具體映射到哪個物理地址,還需要內存管理單元去做映射操作??傊?,linux任務用戶態的堆棧和普通應用程序一樣,由操作系統分配和釋放,對程序員來說不可見,不過因為操作系統的原因,任務用戶程序尋址有限制。如果有機會之后介紹一下linux內存管理的個人理解。

責任編輯:張子龍 來源: 博客園
相關推薦

2010-01-18 17:29:35

VB.NET函數調用

2020-12-16 09:47:01

JavaScript箭頭函數開發

2010-06-28 10:12:01

PHP匿名函數

2010-09-10 16:02:13

SQLCHARINDEX函數

2023-03-10 09:11:52

高性能Go堆棧

2017-04-25 15:30:23

堆棧函數JavaScript

2023-10-27 11:27:14

Go函數

2018-11-05 14:53:14

Go函數代碼

2018-07-09 13:40:24

前端javascript

2012-02-01 10:33:59

Java

2012-04-16 13:47:37

JavaMatlab

2021-09-07 08:33:27

JavaScript TypeScript 函數

2009-08-05 18:34:07

堆棧遍歷

2010-01-27 16:05:06

C++堆棧

2024-04-11 14:04:23

C++編程函數

2023-06-19 09:16:41

CSSstep函數

2024-12-31 00:07:12

2014-11-11 15:25:30

PHPWeb

2022-09-22 11:36:31

隊列Python

2021-06-15 07:33:13

Java函數式編程
點贊
收藏

51CTO技術棧公眾號

久久中文字幕二区| 神马欧美一区二区| 麻豆chinese极品少妇| 亚洲欧美日本国产| 色综合中文字幕国产| 亚洲一区精彩视频| 日本毛片在线观看| 美女爽到高潮91| 欧美夫妻性生活xx| 免费看黄色的视频| a看欧美黄色女同性恋| 一本大道久久a久久精二百| 精品91一区二区三区| 亚洲精品一区二区三区蜜桃| 日韩精品高清不卡| 欧美激情videoshd| 奇米网一区二区| 激情亚洲另类图片区小说区| 欧美视频精品在线| 男女视频网站在线观看| 欧美被日视频| 久久老女人爱爱| 91传媒视频在线观看| 中文字幕免费高清网站| 亚洲视频中文| 俺去了亚洲欧美日韩| 醉酒壮男gay强迫野外xx| 国产一区二区三区免费在线| 在线精品视频一区二区三四| 日韩av中文字幕第一页| 国产一二三区在线观看| 欧美国产综合色视频| 精选一区二区三区四区五区| 国产视频在线一区| 久久精品国产色蜜蜜麻豆| 5278欧美一区二区三区| 精品无码久久久久久久| 91精品国产视频| 中文字幕日韩综合av| 中国美女乱淫免费看视频| 国产精品xxxav免费视频| 88在线观看91蜜桃国自产| 好男人www社区| 欧美xx视频| 欧美性猛交xxxx免费看| 一区二区三区四区精品在线视频| yellow视频在线观看一区二区 | 激情综合久久| 欧美大胆在线视频| 精品国产国产综合精品| 水蜜桃久久夜色精品一区| 亚洲人午夜色婷婷| 六月婷婷七月丁香| 中日韩免视频上线全都免费| 亚洲精品日韩久久久| 日韩综合第一页| 亚洲一二三区视频| 精品国产乱码久久久久久闺蜜| 国产精品久久久久久久99| 99热这里有精品| 91精品国产综合久久久久久 | 成人黄色在线网站| 国产精品二区三区四区| 亚洲女人18毛片水真多| eeuss国产一区二区三区| 国产三级精品在线不卡| 国产91免费看| 久久影音资源网| 日韩av不卡播放| av国产在线观看| 中文字幕日韩一区| 黄色特一级视频| 菠萝蜜视频在线观看www入口| 亚洲成人自拍偷拍| 日韩免费视频播放| 91亚洲视频| 91精品中文字幕一区二区三区| 制服下的诱惑暮生| 秋霞蜜臀av久久电影网免费| 亚洲欧美中文日韩在线| 五月婷婷六月香| 欧美日韩免费| 日本国产高清不卡| 亚洲无码精品在线观看| 国产福利一区二区三区视频在线| 国产精品v欧美精品v日韩| 经典三级在线| 亚洲美腿欧美偷拍| 777久久久精品一区二区三区| 欧美与亚洲与日本直播| 嫩呦国产一区二区三区av| 亚洲精选免费视频| 国产视频九色蝌蚪| 久久麻豆视频| 精品久久久久香蕉网| 97伦伦午夜电影理伦片| 欧美黄色大片在线观看| 亚洲3p在线观看| 自拍偷拍精品视频| 粉嫩aⅴ一区二区三区四区五区| 蜜桃传媒视频第一区入口在线看| 天天综合视频在线观看| 婷婷亚洲久悠悠色悠在线播放| mm1313亚洲国产精品无码试看| 欧美黄色一级| 亚洲无限av看| 日韩av电影网址| 蜜桃av噜噜一区二区三区小说| av一区二区三区免费| 国产精品影院在线| 亚洲风情在线资源站| 手机看片一级片| 丝袜美腿一区二区三区动态图| 久久精品视频在线| 一级片免费在线播放| 成人一级黄色片| 在线成人性视频| jizz内谢中国亚洲jizz| 欧美成人在线直播| 欧美性生交大片| 日韩成人午夜精品| 久久久久久九九九九| 新版中文在线官网| 777午夜精品视频在线播放| 四虎国产精品成人免费入口| 韩国一区二区三区在线观看| 成人精品一区二区三区电影黑人| 青青草手机在线| 亚洲电影第三页| 亚洲精品无码久久久久久久| 日韩在线视频精品| 国产高清视频一区三区| 亚洲av成人精品一区二区三区在线播放 | 91精品一区二区三区久久久久久| 国产成人av一区二区三区不卡| 国产精品久久AV无码| 高清日韩中文字幕| 欧美高清不卡在线| 国产精品国产一区二区三区四区 | 免费观看日韩电影| 欧美污视频久久久| 竹内纱里奈兽皇系列在线观看| 精品免费一区二区三区| 国产三级国产精品国产国在线观看| 日韩av一级片| 视频一区三区| 国产精品扒开腿做爽爽爽视频软件| 亚洲黄色成人网| 日本免费观看视| 99精品国产一区二区三区不卡| 国产无限制自拍| 久久中文字幕导航| 66m—66摸成人免费视频| 色婷婷av一区二区三区之e本道| 一区二区三区欧美| 中国极品少妇xxxx| 伊人久久成人| 久久一区二区精品| 亚洲男人av| 国产亚洲综合久久| 波多野结衣一区二区三区四区| 久久嫩草精品久久久精品一| 毛葺葺老太做受视频| 欧美裸体在线版观看完整版| 国产精品福利久久久| 9i精品一二三区| 538在线一区二区精品国产| 黄色一级视频免费观看| 粉嫩蜜臀av国产精品网站| 精品无码国模私拍视频| 天海翼精品一区二区三区| 国产精品第一页在线| 老司机午夜在线| 精品国产乱码久久久久久影片| 欧美亚洲天堂网| 国产清纯在线一区二区www| 欧美日韩中文不卡| 一区二区三区四区在线观看国产日韩 | 免费极品av一视觉盛宴| 国产精品久久久久av蜜臀| 人妖精品videosex性欧美| av天在线观看| 日韩精品一区二区三区中文精品| 日本免费一二三区| 国产精品女同一区二区三区| 精品久久久网站| 欧美精品久久久久性色| 国产区在线视频| 久久久精品国产99久久精品芒果| 国产又黄又大又粗视频| 色综合咪咪久久网| 99影视tv| 你懂得影院夜精品a| 蜜臀久久99精品久久久久久宅男 | 麻豆精品蜜桃| 色综合视频网站| 精品视频一二三| 欧美一区二区三区视频在线观看| 国产精品suv一区二区三区| 一区在线观看免费| 亚洲av无码国产精品久久| 青青草视频一区| 男人的天堂狠狠干| 欧美成人milf| 欧美精品国产精品久久久| 电影91久久久| 国产精品h在线观看| 亚洲图区一区| 日韩在线视频网站| 无码h黄肉3d动漫在线观看| 欧美日本韩国一区二区三区视频| 亚洲国产综合久久| 亚洲免费三区一区二区| 蜜臀久久99精品久久久久久| 成人高清视频在线观看| 成人黄色一级大片| 视频在线观看一区| 国产主播自拍av| 综合精品一区| 亚洲一区二区三区精品在线观看 | 成人在线网站| 91禁国产网站| 男女羞羞视频在线观看| 日韩在线免费av| 国产高清在线| 亚洲精品少妇网址| 色婷婷视频在线| 欧美一区二区三区影视| 91午夜交换视频| 91久久精品午夜一区二区| 中文字幕亚洲精品在线| 樱花影视一区二区| 亚洲人做受高潮| 欧美激情一区在线观看| 强伦人妻一区二区三区| 成人动漫av在线| 人妻激情偷乱视频一区二区三区| 久久精品国产77777蜜臀| www.日本xxxx| 日韩成人一区二区| 激情 小说 亚洲 图片: 伦| 日韩精品乱码免费| 欧美日韩亚洲自拍| 福利网址在线观看| 国产精品青草综合久久久久99| 中文字幕一区二区三区人妻不卡| 成人的网站免费观看| 国产在线不卡av| 成人激情免费网站| 欲求不满的岳中文字幕| 99精品视频在线观看免费| 国产草草浮力影院| 91小视频在线免费看| 黄色短视频在线观看| 久久免费精品国产久精品久久久久| 波多野结衣福利| 久久精品亚洲精品国产欧美kt∨| 魔女鞋交玉足榨精调教| 国产欧美日韩精品一区| 日本黄区免费视频观看| 中文字幕一区二区在线观看 | 精品国产1区| 日本黑人久久| 日韩成人影院| 7777在线视频| 午夜欧美精品久久久久久久| 真人做人试看60分钟免费| 欧美日韩一卡| 日韩小视频在线播放| 先锋影音国产一区| 一区二区在线播放视频| 久久99精品久久久久久久久久久久 | 精品国产乱码久久久久久图片 | 在线观看国产精品视频| 欧美精品粉嫩高潮一区二区| www.桃色av嫩草.com| 精品精品国产高清一毛片一天堂| 婷婷丁香花五月天| 亚洲欧美一区二区激情| 三区四区在线视频| 九九热精品视频国产| 亚洲精品福利电影| 国产日韩在线亚洲字幕中文| 免费欧美网站| 欧美日韩一区二区视频在线观看| 国产精品二区不卡| 成品人视频ww入口| 日韩和的一区二区| 肉丝美足丝袜一区二区三区四| 久久这里只有精品首页| 国产午夜手机精彩视频| 精品高清美女精品国产区| 中文字幕一二区| 亚洲第一精品夜夜躁人人躁| 成年人在线看| 韩国精品美女www爽爽爽视频| 成人精品三级| 精品国产二区在线| 九一国产在线观看| 成人午夜短视频| 91精品国自产在线| 亚洲伊人伊色伊影伊综合网| 亚洲天堂视频网站| 日韩视频永久免费| www视频在线观看免费| 欧美激情亚洲精品| 日本免费一区二区三区等视频| 精品999在线观看| 亚洲色图国产| 久久综合伊人77777麻豆最新章节| 国产精品自拍三区| 中文字幕网站在线观看| 午夜视频在线观看一区二区三区 | 宅男在线国产精品| 青青操视频在线| 久久久久日韩精品久久久男男| 国产激情欧美| 欧美久久久久久久| 在线欧美日韩| 久久精品无码一区二区三区毛片| 国产视频在线观看一区二区三区| 精品视频一区二区在线观看| 欧美二区三区91| 大胆av不用播放器在线播放 | 欧美黄页免费| 欧美三级华人主播| 中文精品视频| 无码人妻一区二区三区一| 国产精品福利电影一区二区三区四区| 成年人视频在线免费看| 亚洲第一国产精品| 在线三级电影| 亚洲精品欧美极品| 亚洲国产一成人久久精品| 亚洲黄色av片| 国产精品伦理在线| 中文字幕 国产精品| 亚洲欧美日韩另类| 电影天堂国产精品| 欧美日韩成人一区二区三区| 在线亚洲一区| 精品少妇人妻一区二区黑料社区| 高跟丝袜一区二区三区| 色呦呦中文字幕| 97视频免费在线看| 欧美亚洲色图校园春色| 日韩欧美亚洲天堂| 99久久婷婷国产综合精品电影| 日本一区二区三区四区五区| 欧美精品一区二区三| 黄色在线网站噜噜噜| 国产一区二区三区奇米久涩 | 亚洲人成7777| 国产日韩欧美视频在线观看| 久久精品国亚洲| 日韩av综合| 欧美一级片免费播放| 99久久久无码国产精品| 久久久久久久久久久久久久av| 国产视频亚洲精品| 日韩三区在线| 在线一区高清| 国产成人免费在线观看不卡| 精品无码m3u8在线观看| 日韩电影在线观看中文字幕| 男人的天堂一区二区| 91麻豆国产自产在线观看| 久久久久久久黄色片| 国产亚洲欧洲高清| 日本亚洲欧洲无免费码在线| 日本丰满少妇黄大片在线观看| 高潮精品一区videoshd| 国产免费av一区二区| 一区二区欧美激情| 24小时成人在线视频| 国产一区 在线播放| 久久综合色播五月| 91theporn国产在线观看| 欧美激情图片区| 亚洲日产av中文字幕| 亚洲一区二区三区观看| 亚洲一级在线观看| 国产区在线视频| 51午夜精品| 久久视频一区| 2021亚洲天堂| 亚洲香蕉在线观看| 欧美大片91| 免费日韩中文字幕| 亚洲欧美日韩人成在线播放| 水莓100在线视频| 成人精品一区二区三区电影免费 | 欧美日韩人妻精品一区在线| 一本色道久久综合狠狠躁的推荐| av网站在线免费观看| 国模一区二区三区私拍视频| 蜜桃视频第一区免费观看| 日本少妇xxxx动漫| yw.139尤物在线精品视频| 欧美午夜18电影|