3.67
/*
* 3.67.c
*/
typedef struct {
long a[2];
long *p;
} strA;
typedef struct {
long u[2];
long q;
} strB;
strB process(strA a) {
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;
}
# strB process(strA s)
# s in %rdi
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
# long eval(long x, long y, long z)
# x in %rdi, y in %rsi, z in %rdx
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
call process
movq 72(%rsp), %rax
addq 64(%rsp), %rax
addq 80(%rsp), %rax
addq $104, %rsp
ret
A.
104 +------------------+
| |
| |
| |
| |
| |
| |
| |
| |
64 +------------------+ <-- %rdi
| |
| |
| |
| |
| |
| |
32 +------------------+
| z |
24 +------------------+
| &z |
16 +------------------+
| y |
8 +------------------+
| x |
0 +------------------+ <-- %rsp
B.
eval pass a new address %rsp+64 to process
C.
process access s by %rsp+offset, not by %rdi
D.
eval pass address %rsp+64 to process, process store data from here as beginning, finially return this address
E.
104 +------------------+
| |
| |
| |
| |
| |
| |
88 +------------------+
| z |
80 +------------------+
| x |
72 +------------------+
| y |
64 +------------------+ <-- %rdi(eval pass in)
| | \
| | -- %rax(process pass out)
| |
| |
| |
| |
32 +------------------+
| z |
24 +------------------+
| &z |
16 +------------------+
| y |
8 +------------------+
| x |
0 +------------------+ <-- %rsp in eval
| |
-8 +------------------+ <-- %rsp in process
F.
caller find space and pass space address to callee, callee store data on this space area and return this address