新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 談談arm下的函數棧

        談談arm下的函數棧

        作者: 時間:2016-11-20 來源:網絡 收藏

        引言

          這篇文章簡要說說函數是怎么傳入參數的,我們都知道,當一個函數調用使用少量參數(ARM上是少于等于4個)時,參數是通過寄存器進行傳值(ARM上是通過r0,r1,r2,r3),而當參數多于4個時,會將多出的參數壓入棧中進行傳遞(其實在函數調用過程中也會把r0,r1,r2,r3傳遞的參數壓入棧),具體是什么實現的呢,我們看看。

        本文引用地址:http://www.104case.com/article/201611/318805.htm

        函數棧

          首先我們需要了解一下linux下一個進程的內存地址空間是如何布局的,在linux中,0~3G的虛擬地址為進程所有,3G~4G由內核所使用,每一個進程都有自己獨立的0~3G內存地址空間。當進程進行函數調用時,我們都知道傳入被調用函數的參數是通過棧進行操作的,這里我們只需要簡單了解一下linux的內存地址空間中的棧是自頂向下生長的,就是棧底出于高地址處,棧頂出于低地址處。

          好的,簡單了解了內存地址空間的棧后,我們還需要簡單了解一下EBP和ESP這兩個寄存器,EBP是用保存棧低地址的,而ESP用于保存棧頂地址,而每一次函數調用會涉及到一個棧幀,

        舉個實例詳細說明一下一個函數幀的特點,比如

        1 /* B被A調用2  * 參數:data1, data2, data33  * 局部變量: s1, s2, s3 */4 void B (int data1, int data2, int data3)5 {6     int b_s1;7     int b_s2;8     int b_s3;9 }10  11 /* A調用B函數 */12 void A (void)13 {14     int a_s1;15     int a_s2;16     int a_s3;17     18     B (1, 2, 3);19     printf ("1n");20 }

        在以上例子中棧幀情況如下圖所示

          從圖例中可以看出,當A函數沒有調用B函數時,A函數的棧幀只保存著局部變量,而EBP(棧底指針)指向的是A函數的函數棧幀頭,而當A函數調用B函數時,A函數會將B函數所需要的參數從右往左壓入棧(在例子中先壓入3,之后是2,最后是1),之后會將A調用完B之后所需要運行的第一條指令壓入棧,此時建立一個B的棧幀,具體流程:

        • 從右往左將B函數所需參數壓入棧
        • 壓入執行完B函數之后的第一條指令地址
        • 建立B棧幀
        • 壓入A棧幀的棧底
        • 壓入B函數保護的寄存器
        • 壓入B函數的局部變量

        小結

          其實每一種處理器架構所使用的方式都不一樣,在arm上我幾個參數和不定參數的情況通過匯編代碼查看又不相同,之后反匯編后研究透了會再發布一篇博文專門說這個,現在這篇就當做一個入門知識吧。



        關鍵詞: arm函數

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 海伦市| 宁国市| 固始县| 乐业县| 淄博市| 万山特区| 松江区| 红安县| 德庆县| 安龙县| 高雄市| 杂多县| 蚌埠市| 遂川县| 怀化市| 乐业县| 东辽县| 太仓市| 肃宁县| 永城市| 河间市| 岗巴县| 吉安县| 台东市| 开平市| 繁昌县| 刚察县| 临武县| 奈曼旗| 天门市| 类乌齐县| 遂昌县| 武穴市| 丹巴县| 铁岭县| 泰州市| 会昌县| 上饶市| 长泰县| 安图县| 高邮市|