#include <stdio.h>
void hello() {
int i = 0;
printf("i = %d, hello world\n", i);
}
int main() {
hello();
return 0;
}
hello() 前(在 main 內)的寄存器狀態(gdb) info registers
eax 0xbff644a4 ecx 0xbff64420 edx 0x1
ebx 0xb7f2fff4 esp 0xbff64400 ebp 0xbff64408
eip 0x80483f7 <main+17> // call hello 前
hello() 後的寄存器狀態(gdb) info registers
esp 0xbff643e0 ebp 0xbff643f8
eip 0x80483ca <hello+6>
main 的 esp (0xbff64400) 減去 hello 的 ebp (0xbff643f8) = 8 位元組。
檢查 hello 棧幀內容:
(gdb) x 0xbff643f8 // *(ebp) = 0xbff64408 → main 的 ebp
(gdb) x 0xbff643fc // *(ebp+4) = 0x080483fc → 返回地址 (main+22)
main 反組譯對照0x080483e6 <main+0>: lea 0x4(%esp),%ecx
0x080483ea <main+4>: and $0xfffffff0,%esp // 16-byte 對齊
0x080483ed <main+7>: pushl -0x4(%ecx)
0x080483f0 <main+10>: push %ebp // 保存 main ebp
0x080483f1 <main+11>: mov %esp,%ebp // 建立 main ebp
0x080483f3 <main+13>: push %ecx
0x080483f4 <main+14>: sub $0x4,%esp
0x080483f7 <main+17>: call 0x80483c4 <hello> // 壓入返回地址
...
call 指令壓入返回地址(4 bytes)hello 序言 push %ebp; mov %esp,%ebp 再壓入 main 的 ebp(4 bytes)esp_main - ebp_hello = 8 完全吻合hello.ebp → main.ebp → main.ret_addr