结构体作为传递和返回值的小例子
当C用struct 传递并返回值也是struct 时,编译器是如何处理的哪,下面是gcc的处理方式.#include <stdio.h>
#include <stdlib.h>
struct sa {
int a;
int b;
char c;
};
struct sa fun1(struct sa psa)
{
psa.a=1;
psa.b=99;
psa.c='a';
return(psa);
}
struct sa ss;
int main()
{
struct sa k;
struct sa ll;
k.a=11;
k.b=12;
k.c='0';
ll=fun1(k);
printf("%d,%d,%c",k.a,k.b,k.c);
printf("hello,world!");
printf("%d,%d,%c",ll.a,ll.b,ll.c);
return(0);
}
gcc的处理方式,注意fun1中
"movl 8(%ebp), %edx"
和
" movl %edx, %eax"
等几句.
.file "test5.c"
.text
.globl fun1
.type fun1,@function
fun1:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %edx //ll的地址保存到edx
movl $1, 12(%ebp) //psa.a=1
movl $99, 16(%ebp) //psa.b=99
movb $97, 20(%ebp) //psa.c='a'
movl 12(%ebp), %eax //psa.a 放到eax寄存器,实际上在fun1内已经对main中ll进行赋值了.
movl %eax, (%edx) //ll.a=psa.a
movl 16(%ebp), %eax
movl %eax, 4(%edx) //ll.b=psa.b
movl 20(%ebp), %eax
movl %eax, 8(%edx) //ll.c=psa.c
movl %edx, %eax //eax 存放ll的地址
leave
ret $4
.Lfe1:
.size fun1,.Lfe1-fun1
.section .rodata
.LC0:
.string "%d,%d,%c"
.LC1:
.string "hello,world!"
.text
.globl main
.type main,@function
main:
pushl %ebp
movl %esp, %ebp
subl $40, %esp //本地变量空间
andl $-16, %esp //对齐
movl $0, %eax
subl %eax, %esp
movl $11, -24(%ebp)//k.a=11
movl $12, -20(%ebp)//k.b=12
movb $48, -16(%ebp)//k.c='0'
leal -40(%ebp), %eax //ll的地址
pushl -16(%ebp)//k.c
pushl -20(%ebp)//k.b
pushl -24(%ebp)//k.a
pushl %eax//压入ll的地址,以便fun1能对其进行赋值
call fun1
addl $12, %esp
movsbl -16(%ebp),%eax
pushl %eax
pushl -20(%ebp)
pushl -24(%ebp)
pushl $.LC0
call printf
addl $16, %esp
subl $12, %esp
pushl $.LC1
call printf
addl $16, %esp
movsbl -32(%ebp),%eax
pushl %eax
pushl -36(%ebp)
pushl -40(%ebp)
pushl $.LC0
call printf
addl $16, %esp
movl $0, %eax
leave
ret
.Lfe2:
.size main,.Lfe2-main
.comm ss,12,4
.ident "GCC: (GNU) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)"
[ 本帖最后由 system888net 于 2008-6-11 11:23 编辑 ] 你烦不烦的,C版说了不够,还要到这里贴 原帖由 mnf 于 2008-6-9 23:46 发表 http://linux.chinaunix.net/bbs/images/common/back.gif
你烦不烦的,C版说了不够,还要到这里贴
谦虚使人进步 原帖由 mnf 于 2008-6-9 23:46 发表 http://linux.chinaunix.net/bbs/images/common/back.gif
你烦不烦的,C版说了不够,还要到这里贴
............................................................
[ 本帖最后由 chzCPU 于 2008-6-10 00:18 编辑 ] :) 观点都是一样的,都是为了说明同一个问题.觉得有汇编更能说明stack和eax配合传递struct 的过程,而且感觉这个问题跟编译器有关,有必要在这个论坛也发一下.
[ 本帖最后由 system888net 于 2008-6-10 00:16 编辑 ] 原帖由 system888net 于 2008-6-10 00:08 发表 http://linux.chinaunix.net/bbs/images/common/back.gif
:) 观点都是一样的,都是为了说明同一个问题.觉得有汇编更能说明stack和eax配合传递struct 的过程,而且感觉这个问题跟编译器有关,有必要在这个论坛也发一下.
:mrgreen: :mrgreen:很佩服你! 不但出动了马甲造势,还在C版沸沸扬扬忽悠人。
哈哈~ 你好样的。 继续~~ 兄弟看着你 原帖由 chzCPU 于 2008-6-10 00:04 发表 http://linux.chinaunix.net/bbs/images/common/back.gif
............................................................
:mrgreen: :mrgreen:别编辑你的回复呀!
着急了,是吧。继续~ 兄弟我看着你的戏 :mrgreen: :mrgreen: 写的太不详细,你既然是在发帖子,就应该仔细说明gcc的处理方式,比如保留在什么地方,谁来清栈........ 原帖由 cjaizss 于 2008-6-10 08:46 发表 http://linux.chinaunix.net/bbs/images/common/back.gif
写的太不详细,你既然是在发帖子,就应该仔细说明gcc的处理方式,比如保留在什么地方,谁来清栈........
提醒的对.
已加了一些说明,不知道道能否说的清楚些.
[ 本帖最后由 system888net 于 2008-6-11 15:28 编辑 ] 也就是说明: 在gcc里, 对于结构体的返回:return(psa); 这个动作实际上是在fun1内的对ll各成员赋值的一个,而fun1内对ll的识别是靠main调用fun1时传入的ll的地址来确定的.
页:
[1]
2