對C的函數堆棧的內容一直只有個模糊的印象。今天寫了個小程序以加深自己對函數堆棧的理解。經過打印輸出,發現
調用函數時,系統會依次往堆棧中壓入如下數據:
- 從右到左依次壓入實參
- 函數的返回地址
- 調用函數的棧基址EBP
- 3個寄存器的值
- 局部變量
測試代碼如下:
/* This file research C stack */
#include <stdio.h>
unsigned int return_addr;
static void fun3(int q)
{
unsigned int d= 0x11112;
printf("addr of d=%x\n",d);
return;
}
void print_stack_hex(unsigned int *addr,int num)
{
int i;
for(i = 0;i < num;i++)
{
printf("addr=%p,val=%x\n",addr+i,*(addr+i));
}
return;
}
void fun2(int b,int a)
{
unsigned int c= 0xa5a6a7a8;
printf("addr of c=%p\n",&c);
__asm__("movl 4(%ebp),%eax");
__asm__("movl %eax,return_addr");
printf("return ip of fun2=%x\n",return_addr);
print_stack_hex(&c,12);
return;
}
void fun1(int a)
{
unsigned int b = 0x5a6a7a8a;
fun2(0xaa58,0xaa56);
return;
}
測試結果如下:
fun1=0x80485af,fun2=0x8048540
addr of c=0xbfc19af8
return ip of fun2=80485ce
addr=0xbfc19af8,val=a5a6a7a8
addr=0xbfc19afc,val=e1d3e000
addr=0xbfc19b00,val=b772a000
addr=0xbfc19b04,val=b7535798
addr=0xbfc19b08,val=bfc19b38
addr=0xbfc19b0c,val=80485ce
addr=0xbfc19b10,val=aa58
addr=0xbfc19b14,val=aa56
addr=0xbfc19b18,val=bfc19b68
addr=0xbfc19b1c,val=b7578696
addr=0xbfc19b20,val=b76e1d60
addr=0xbfc19b24,val=804866a
以後隨着理解的深入,我會繼續這個主題的探討。