这个作业要查看GCC为参数和返回值中有结构的函数产生的代码,由此可以看到这些语言特性通常是如何实现的。
下面的C代码中有一个函数process,它用结构作为参数和返回值,还有一个函数eval,它调用process:
typedef struct { long a[2]; long *p; } strA; typedef struct { long u[2]; long q; } strB; strB process(strA s) { strB r; r.u[0]=s.a[1]; r.u[1]=s.a[0]; r.q= *s.p; return r; } long eval(long x, long y, long z){ strA s; s.a[0]=x; s.a[1]=y; s.p=&z; strB r=process(s); return r.u[0]+r.u[1]+r.q; }
GCC为这两个函数产生下面的代码:
process: movq %rdi,%rax movq 24(%rsp),%rdx movq (%rdx),%rdx movq 16(%rsp),%rcx movq %rcx,(%rdi) movq 8(%rsp),%rcx movq %rcx,8(%rdi) movq %rdx,16(%rdi) ret
eval: subq $104,%rsp movq %rdx,24(%rsp) leaq 24(%rsp),%rax movq %rdi,(%rsp) movq %rsi,8(%rsp) movq %rax,16(%rsp) leaq 64(%rsp),%rdi ca;ll process movq 72(%rsp),%rax addq 64(%rsp),%rax addq 80(%rsp),%rax addq $104,%rsp ret
A. 从eval函数的第2行我们可以看到,它在栈上分配了 104个字节。画出eval的栈帧,给出它在调用process前存储在栈上的值。
B. eval调用process时传递了什么值?
C. process的代码是如何访问结构参数s的元素的?
D. process的代码是如何设置结果结构r的字段的?
E. 完成eval的栈帧图,给出在从process返回后eval是如何访问结构r的元素的。
F. 就如何传递作为函数参数的结构以及如何返回作为函数结果的结构值,你可以看出什么通用的原则?