结构体作为传递和返回值的小例子

发布于 2022-09-19 12:09:43 字数 7173 浏览 23 评论 0

当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 编辑 ]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

请爱~陌生人 2022-09-26 12:09:43

你烦不烦的,C版说了不够,还要到这里贴

酒儿 2022-09-26 12:09:43

原帖由 mnf 于 2008-6-9 23:46 发表
你烦不烦的,C版说了不够,还要到这里贴

谦虚使人进步

青巷忧颜 2022-09-26 12:09:43

原帖由 mnf 于 2008-6-9 23:46 发表
你烦不烦的,C版说了不够,还要到这里贴

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

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

做个ˇ局外人 2022-09-26 12:09:43

观点都是一样的,都是为了说明同一个问题.觉得有汇编更能说明stack和eax配合传递struct 的过程,而且感觉这个问题跟编译器有关,有必要在这个论坛也发一下.

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

凉城已无爱 2022-09-26 12:09:43

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

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

念三年u 2022-09-26 12:09:43

原帖由 chzCPU 于 2008-6-10 00:04 发表

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

  别编辑你的回复呀!

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

怎会甘心 2022-09-26 12:09:43

写的太不详细,你既然是在发帖子,就应该仔细说明gcc的处理方式,比如保留在什么地方,谁来清栈........

横笛休吹塞上声 2022-09-26 12:09:43

原帖由 cjaizss 于 2008-6-10 08:46 发表
写的太不详细,你既然是在发帖子,就应该仔细说明gcc的处理方式,比如保留在什么地方,谁来清栈........

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

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

み零 2022-09-26 12:09:43

也就是说明: 在gcc里, 对于结构体的返回:return(psa); 这个动作实际上是在fun1内的对ll各成员赋值的一个,而fun1内对ll的识别是靠main调用fun1时传入的ll的地址来确定的.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文