C語言堆棧幀的介紹與創(chuàng)建
什么是堆棧幀?
堆棧幀(stack frame)是一塊堆棧保留區(qū)域,用于存放被傳遞的實際參數(shù),子程序的返回值、局部變量以及被保存的寄存器。
堆棧幀的創(chuàng)建方法🐱👤【32bit Windows】
(1)被傳遞的實際參數(shù)。如果有,則壓入堆棧;
(2)當(dāng)子程序被調(diào)用時,使該子程序的返回值壓入堆棧。如果使用寄存器保存返回值,則跳過此步;
(3)子過程返回地址入棧;
(4)子程序開始執(zhí)行時,EBP被壓入堆棧;
(5)設(shè)置EBP等于ESP。從現(xiàn)在開始,EBP就變成了該子程序所有參數(shù)的引用基址;
(6)如果有局部變量,修改ESP以便在堆棧中為這些變量預(yù)留空間;
(7)如果需要保存寄存器,則將它們?nèi)霔#?/p>
我們來看一段code👇
#include<stdio.h>
int print_string(const char * str)
{
/* EBP被壓入堆棧,對應(yīng)上述步驟(4) */
//00FE18A0 push ebp
/* 設(shè)置EBP等于ESP,對應(yīng)上述步驟(5) */
//00FE18A1 mov ebp,esp
/* 雖然我們沒有局部變量,但是編譯器還是預(yù)留了空間,對應(yīng)上述步驟(6) */
//00FE18A3 sub esp,0C0h
/* 保存寄存器,對應(yīng)上述步驟(7) */
//00FE18A9 push ebx
//00FE18AA push esi
//00FE18AB push edi
printf("%s\n", str);
/* 將printf函數(shù)的入?yún)喝攵褩?*/
//00FE18C1 mov eax,dword ptr [str]
//00FE18C4 push eax
//00FE18C5 push offset string "%s\n" (0FE7B30h)
//00FE18CA call _printf (0FE10CDh)
//00FE18CF add esp,8
return 1;
/* 使用寄存器存儲返回值 */
//00FE18D2 mov eax,1
}
int main()
{
char* str = "Hello World";
/* 將"Hello World"的地址存在str變量中 */
//00FE1865 mov dword ptr [str],offset string "Hello World" (0FE7B34h)
print_string(str);
/* 將str 中的值存在eax寄存器中 */
//00FE186C mov eax,dword ptr [str]
/* eax壓棧,對應(yīng)上述步驟(1) */
//00FE186F push eax
/* 這里我們使用寄存器存儲返回值,所以沒有步驟(2) */
/* call指令會自動將返回地址壓棧,對應(yīng)上述步驟(3) */
//00FE1870 call _print_string (0FE13B1h)
/* 清空 print_string函數(shù)的入?yún)⒖臻g */
//00FE1875 add esp,4
return 0;
//00FE1878 xor eax,eax
}
我們再通過一張圖來解釋一下:
//我們的匯編code如下 print_string PROC push ebp // 保存基址寄存器 mov ebp,esp // 堆棧幀基址 push ecx push edx // 保存寄存器 mov eac,[ebx+8] // 取堆棧參數(shù) . . pop edx // 恢復(fù)被保存的寄存器 pop ecx pop ebp // 恢復(fù)基址指針 ret // 清除堆棧 print_string ENDP
函數(shù)print_string() 對應(yīng)的堆棧幀如下圖👇

總結(jié)
到此這篇關(guān)于C語言堆棧幀的文章就介紹到這了,更多相關(guān)C語言堆棧幀內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
利用Matlab實現(xiàn)圖像亮度分布統(tǒng)計圖
這篇文章主要介紹了如何利用Matlab實現(xiàn)圖像亮度分布統(tǒng)計圖的繪制,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)Matlab有一定的幫助,感興趣的可以了解一下2022-05-05
VScode搭建OpenCV環(huán)境的詳細(xì)步驟
用vscode來寫opencv代碼需要自己編譯OpenCV,主要用到MinGW-w64和CMake工具。接下來通過本文給大家介紹VScode搭建OpenCV環(huán)境的相關(guān)知識,需要的朋友可以參考下2021-11-11

