在x86平台下的函数参数传递

在学习ARM过程中,想要了解函数调用时参数传递是如何用堆栈来实现的,就需要写一段代码将每个参数的地址打印出来,查看堆栈的存储内容;以重写printf为例,首先查看x_86平台下的各数据类型所占的字节数,

sizeof int           = 4
sizeof char        = 1
sizeof float        = 4
sizeof double    = 8
sizeof char *      = 4
sizeof int  *        = 4
sizeof flaot*       = 4
sizeof double*   =4
sizeof int **       = 4

定义一个重写 printf 的函数,

int test_printf(const char *format, ...)

再定义一个结构体,在main中定义一个结构体变量,赋值,并传递给test_printf()函数,在test_printf中通过指针的移动进行访问

struct person{
    char *name;
    int age;
    char score;
    int id;
};//定义结构体

main:

struct person per= {"www.100ask.org",21,'A',123456};

在main函数中向test_printf()传递三个参数,通过指针的移动进行访问,并将每个变量的地址打印

push_test("abcd",123,per);  //传递参数

 

int test_printf(const char *format, ...)
{
    char *p =(char *) &format; //将一个char型指针指向第一个参数的地址
    int i;
    struct person  per1;


    printf("p value :0x%x\n",p); //打印p的值,就是第一个参数的地址
    printf("p addr :0x%x\n",&p);//打印p的地址
    printf("arg1 : %s\n",format);//打印出第一个参数
    printf("format addr :0x%x\n",&format);
  
    printf("/-------------------------1\n");
    p = p + (sizeof(char *));//将指针向上移动,移动第一个参数的大小
    printf("p value :0x%x\n",p);//打印出现指针的值

    i = *((int *)p);//将p强制类型转换成指向int型的指针,并把指向的内容赋给变量i
    printf("arg2 : %d\n",i);//打印出变量i
    printf("&i = %p\n",&i);//打印出i的地址


    printf("/-------------------------2\n");
    p = p + sizeof(int);//再将指针向上移动,移动第二个参数的大小
    per1 = *((struct person*)p);//将指针强制类型转换为指向结构体的指针,并将指向的内容赋给per1
    printf("p value :0x%x\n",p);//打印出现在指针的值

    printf(" &per1.name  = %p ,  pe1.name  = %s\n" ,&per1.name,per1.name);
    printf(" &per1.age     = %p ,  pe1.age     = %d\n" ,&per1.age ,per1.age );
    printf("&per1.score   = %p ,  pe1.score   = %c\n" ,&per1.score,per1.score);
    printf("&per1.id         = %p ,  pe1.id         = %d\n" ,&per1.id,per1.id);

//打印出结构体变量的地址与值

使用32位编译器进行编译

gcc -m32 -o my_printf my_printf.c

p value :0xffb01210
p addr :0xffb011fc
arg1 : abcd
format addr :0xffb01210
/-------------------------1
p value :0xffb01214
arg2 : 123
&i = 0xffb011f8
/-------------------------2
p value :0xffb01218
arg3 : .name = www.100ask.org; .age = 21; .score = A; .id = 123456
 &per1.name = 0xffb011c8 ,  pe1.name = www.100ask.org
  &per1.age = 0xffb011cc ,   pe1.age = 21
&per1.score = 0xffb011d0 , pe1.score = A
   &per1.id = 0xffb011d4 ,    pe1.id = 123456

由输出参数成功可见,参数在栈中由低地址到高地址依次排列。地址的间隔为各个数据类型所占的内存大小。变量的地址在堆栈中较低于参数的地址,也是依次排列。通过不断的向高地址移动指针,即可将参数不断地读入函数中。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值