int g(int x) { return x + 3; }
int f(int x) { return g(x); }
int main() { return f(8) + 1; }
編譯:gcc -m32 -S test.c -o test.s 獲取 AT&T 語法彙編。
鏈接加載:程序從 main 入口開始執行,動態鏈接器完成符號解析後跳轉到用戶代碼。

圖1 主要指令序列
main 啟動:建立棧幀,分配局部空間pushl $8:壓入參數 8call f:關鍵動作 — 壓入返回地址(下一條指令 EIP),EIP 跳轉到 f 入口f:建立棧幀,pushl 8(%ebp) 取參數,call gg:movl 8(%ebp), %eax 取參數,addl $3, %eax 計算,leave/ret 返回f 收到返回值在 EAX,leave/ret 返回main 收到 EAX,addl $1, %eax,最終 leave/ret 交還控制權給運行時
圖2 調用 f 時棧狀態

圖3 執行留存棧幀
push EIP; jmp target,自動保存返回地址mov esp, ebp; pop ebp,一鍵銷毀棧幀EAXmain → f → g → f → main,每層獨立棧幀,互不干擾# 生成帶調試信息的彙編 gcc -m32 -g -O0 test.c -o test objdump -d -M intel test > test.asm # GDB 動態觀察 gdb ./test (gdb) break main (gdb) run (gdb) disas /m (gdb) info registers (gdb) x/20x $esp # 觀察棧內容
反彙編揭示了高級語言構造如何映射到機器指令。掌握 call/ret、棧幀、參數傳遞、返回值機制,是逆向分析、性能調優、嵌入式調試的基石。