C語言函數(shù)調(diào)用堆棧框架

堆棧是C語言程序運行時必須的一個記錄調(diào)用路徑參數(shù)的空間

????? -- 函數(shù)調(diào)用堆??蚣?/b>
????? -- 傳遞參數(shù)
????? -- 保存返回地址
????? -- 提供局部變量空間

* 函數(shù)的返回值默認使用 eax 寄存器存儲返回給上一級函數(shù)

了解堆棧存在的目的和編譯器對堆棧使用的規(guī)則是理解操作系統(tǒng)一些關(guān)鍵性代碼的基礎(chǔ)


堆棧寄存器

????? -- ebp 基址指針(base pointer),在C語言中用作記錄當前函數(shù)調(diào)用基址
????? -- esp 堆棧指針(stack pointer)

堆棧操作

????? -- push 棧頂?shù)刂窚p少4個字節(jié)(32位)
????? -- pop 棧頂?shù)刂吩黾?個字節(jié)(32位)

堆棧操作中涉及的其它關(guān)鍵寄存器

????? cs : eip? 總是指向下一條指令的地址
????? -- 順序執(zhí)行:總是指向地址連續(xù)的下一條指令
????? -- 跳轉(zhuǎn)/分支:執(zhí)行這樣的指令的時候,cs:eip的值會根據(jù)程序需要被修改
????? -- call:將當前cs:eip的值壓入棧頂,cs:eip指向被調(diào)用函數(shù)的入口地址
????? -- ret:從棧頂彈出原來保存在這里的cs:eip的值,放入cs:eip
????? -- 發(fā)生中斷時,CPU把寄存器的值壓到內(nèi)核堆棧里,eip指向中斷處理程序的入口地址


Stack memory + operations

堆棧操作

Stack grows down
Use to implement procedure calls
(* 號表示eip寄存器不能被直接修改,只能通過特殊指令間接修改)



函數(shù)調(diào)用堆??蚣?/b>


函數(shù)的堆棧框架

call target

????? -- 執(zhí)行call之前
????? -- 執(zhí)行call時,cs:eip原來的值指向call下一條指令,該值被保存到棧頂,然后cs:eip的值指向target的入口地址

進入target(Prologue)

????? -- 第一條指令:pushl %ebp
????? -- 第二條指令:movl %esp, %ebp
????? -- 函數(shù)體中的常規(guī)操作,可能會壓棧、出棧

退出target(Epilogue)

????? -- 第一條指令:movl %ebp, %esp
????? -- 第二條指令:popl %ebp
????? -- ret


Gcc calling conventions

Gcc calling conventions

Saved %ebp’s form a chain, can walk stack
Arguments and locals at fixed offsets from EBP


通過反匯編一個簡單的C程序,分析匯編代碼理解C語言函數(shù)調(diào)用堆??蚣?br>

C程序

C程序

匯編代碼

匯編代碼


觀察另一段小程序

一段小程序


觀察main中的局部變量

觀察main中的局部變量


如何傳遞參數(shù)給p2

如何傳遞參數(shù)給p2

Q:p2的返回值是如何返回給main的?


觀察p2的堆棧框架

觀察p2的堆??蚣?/div>


(完)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容