免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4897 | 回复: 10
打印 上一主题 下一主题

结构体作为传递和返回值的小例子 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-06-09 23:09 |只看该作者 |倒序浏览
当C用struct 传递并返回值也是struct 时,编译器是如何处理的哪,下面是gcc的处理方式.


  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. struct sa {
  4.    int a;
  5.    int b;
  6.    char c;
  7. };

  8. struct sa fun1(struct sa psa)
  9. {
  10.    psa.a=1;
  11.    psa.b=99;
  12.    psa.c='a';
  13.    return(psa);
  14. }
  15. struct sa ss;

  16. int main()
  17. {
  18.    struct sa k;
  19.    struct sa ll;
  20.    k.a=11;
  21.    k.b=12;
  22.    k.c='0';
  23.    ll=fun1(k);
  24.    printf("%d,%d,%c",k.a,k.b,k.c);
  25.    printf("hello,world!");
  26.    printf("%d,%d,%c",ll.a,ll.b,ll.c);
  27.    return(0);
  28. }

复制代码



gcc的处理方式,注意fun1中
        "movl        8(%ebp), %edx"
   和
"        movl        %edx, %eax"
   等几句.


  1.         .file        "test5.c"
  2.         .text
  3. .globl fun1
  4.         .type        fun1,@function
  5. fun1:
  6.         pushl        %ebp
  7.         movl        %esp, %ebp
  8.         movl        8(%ebp), %edx     //ll的地址保存到edx
  9.         movl        $1, 12(%ebp)      //psa.a=1
  10.         movl        $99, 16(%ebp)     //psa.b=99
  11.         movb        $97, 20(%ebp)     //psa.c='a'
  12.         movl        12(%ebp), %eax    //psa.a 放到eax寄存器,实际上在fun1内已经对main中ll进行赋值了.
  13.         movl        %eax, (%edx)      //ll.a=psa.a
  14.         movl        16(%ebp), %eax   
  15.         movl        %eax, 4(%edx)     //ll.b=psa.b
  16.         movl        20(%ebp), %eax
  17.         movl        %eax, 8(%edx)     //ll.c=psa.c
  18.         movl        %edx, %eax         //eax 存放ll的地址
  19.         leave
  20.         ret        $4
  21. .Lfe1:
  22.         .size        fun1,.Lfe1-fun1
  23.         .section        .rodata
  24. .LC0:
  25.         .string        "%d,%d,%c"
  26. .LC1:
  27.         .string        "hello,world!"
  28.         .text
  29. .globl main
  30.         .type        main,@function
  31. main:
  32.         pushl        %ebp
  33.         movl        %esp, %ebp
  34.         subl        $40, %esp    //本地变量空间
  35.         andl        $-16, %esp   //对齐
  36.         movl        $0, %eax
  37.         subl        %eax, %esp
  38.         movl        $11, -24(%ebp)  //k.a=11
  39.         movl        $12, -20(%ebp)  //k.b=12
  40.         movb        $48, -16(%ebp)  //k.c='0'
  41.         leal        -40(%ebp), %eax //ll的地址
  42.         pushl        -16(%ebp)  //k.c
  43.         pushl        -20(%ebp)  //k.b
  44.         pushl        -24(%ebp)  //k.a
  45.         pushl        %eax  //压入ll的地址,以便fun1能对其进行赋值
  46.         call        fun1
  47.         addl        $12, %esp
  48.         movsbl        -16(%ebp),%eax
  49.         pushl        %eax
  50.         pushl        -20(%ebp)
  51.         pushl        -24(%ebp)
  52.         pushl        $.LC0
  53.         call        printf
  54.         addl        $16, %esp
  55.         subl        $12, %esp
  56.         pushl        $.LC1
  57.         call        printf
  58.         addl        $16, %esp
  59.         movsbl        -32(%ebp),%eax
  60.         pushl        %eax
  61.         pushl        -36(%ebp)
  62.         pushl        -40(%ebp)
  63.         pushl        $.LC0
  64.         call        printf
  65.         addl        $16, %esp
  66.         movl        $0, %eax
  67.         leave
  68.         ret
  69. .Lfe2:
  70.         .size        main,.Lfe2-main
  71.         .comm        ss,12,4
  72.         .ident        "GCC: (GNU) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)"
复制代码

[ 本帖最后由 system888net 于 2008-6-11 11:23 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-06-09 23:46 |只看该作者
你烦不烦的,C版说了不够,还要到这里贴

论坛徽章:
0
3 [报告]
发表于 2008-06-09 23:54 |只看该作者
原帖由 mnf 于 2008-6-9 23:46 发表
你烦不烦的,C版说了不够,还要到这里贴



谦虚使人进步

论坛徽章:
0
4 [报告]
发表于 2008-06-10 00:04 |只看该作者
原帖由 mnf 于 2008-6-9 23:46 发表
你烦不烦的,C版说了不够,还要到这里贴



............................................................

[ 本帖最后由 chzCPU 于 2008-6-10 00:18 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2008-06-10 00:08 |只看该作者
观点都是一样的,都是为了说明同一个问题.觉得有汇编更能说明stack和eax配合传递struct 的过程,而且感觉这个问题跟编译器有关,有必要在这个论坛也发一下.

[ 本帖最后由 system888net 于 2008-6-10 00:16 编辑 ]

论坛徽章:
0
6 [报告]
发表于 2008-06-10 00:38 |只看该作者
原帖由 system888net 于 2008-6-10 00:08 发表
观点都是一样的,都是为了说明同一个问题.觉得有汇编更能说明stack和eax配合传递struct 的过程,而且感觉这个问题跟编译器有关,有必要在这个论坛也发一下.


  很佩服你! 不但出动了马甲造势,还在C版沸沸扬扬忽悠人。
哈哈~ 你好样的。 继续~~ 兄弟看着你

论坛徽章:
0
7 [报告]
发表于 2008-06-10 00:40 |只看该作者
原帖由 chzCPU 于 2008-6-10 00:04 发表



............................................................



  别编辑你的回复呀!

着急了,是吧。继续~ 兄弟我看着你的戏   

论坛徽章:
3
2015年迎新春徽章
日期:2015-03-04 09:56:11数据库技术版块每日发帖之星
日期:2016-08-03 06:20:00数据库技术版块每日发帖之星
日期:2016-08-04 06:20:00
8 [报告]
发表于 2008-06-10 08:46 |只看该作者
写的太不详细,你既然是在发帖子,就应该仔细说明gcc的处理方式,比如保留在什么地方,谁来清栈........

论坛徽章:
0
9 [报告]
发表于 2008-06-11 11:27 |只看该作者
原帖由 cjaizss 于 2008-6-10 08:46 发表
写的太不详细,你既然是在发帖子,就应该仔细说明gcc的处理方式,比如保留在什么地方,谁来清栈........


提醒的对.
已加了一些说明,不知道道能否说的清楚些.

[ 本帖最后由 system888net 于 2008-6-11 15:28 编辑 ]

论坛徽章:
0
10 [报告]
发表于 2008-06-11 11:34 |只看该作者
也就是说明: 在gcc里, 对于结构体的返回:return(psa); 这个动作实际上是在fun1内的对ll各成员赋值的一个,而fun1内对ll的识别是靠main调用fun1时传入的ll的地址来确定的.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP