对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
以后随着理解的深入,我会继续这个主题的探讨。