- Consider the C as well as disassembled code below:
int main(int argc,char **argv)
{
long x=3,y=9,z=0;
z = top(x,y);
return z;
}
long top(long x,long y) {
x = x + y;
return leaf(x,y);
}
long leaf(long y,long z) {
z = y - z;
return z;
}
1 00000000004004d6 <leaf>:
2 4004d6: 48 89 f8 mov %rdi,%rax
3 4004d9: 48 29 f0 sub %rsi,%rax
4 4004dc: c3 retq
5 00000000004004dd <top>:
6 4004dd: 48 01 f7 add %rsi,%rdi
7 4004e0: b8 00 00 00 00 mov $0x0,%eax
8 4004e5: e8 ec ff ff ff callq 4004d6
9 4004ea: f3 c3 repz retq
10 00000000004004ec <main>:
11 4004ec: be 09 00 00 00 mov $0x9,%esi
12 4004f1: bf 03 00 00 00 mov $0x3,%edi
13 4004f6: b8 00 00 00 00 mov $0x0,%eax
14 4004fb: e8 dd ff ff ff callq 4004dd
15 400500: f3 c3 repz retq
Fill the table with appropriate values. See Figure.27 in page 243 as well as the Practice problem 3.32 of page 244-245 for reference.
Line number | PC | Instruction | %rdi | %rsi | %rax | %rsp | *%rsp | Description |
14 | 4004fb | callq | 3 | 9 | 0 | 0x7fffffffe820 | --- | Call top(x,y) |
--- | | | | | | | | |
6 | | | | | | | | |
7 | | | | | | | | |
8 | | | | | | | | |
--- | | | | | | | | |
2 | | | | | | | | |
3 | | | | | | | | |
4 | | | | | | | | |
--- | | | | | | | | |
9 | | | | | | | | |
--- | | | | | | | | |
15 | | | | | | | | |
- Consider a function P, which generates local values a-c by simple local computation and d-f by calling Q(), R(), and S(). (See Practice problem 3.34 in page 252 for reference.)
long P(long x,long y,long z) {
long a = ...;
long b = ...;
long c = ...;
long d = ...;
long e = ...;
long f = ...;
return d + e + f;
}
0000000000000022 <P>:
22: 55 push %rbp
23: 53 push %rbx
24: 48 83 ec 20 sub $0x20,%rsp
28: 48 83 c7 01 add $0x1,%rdi
2c: 48 89 7c 24 18 mov %rdi,0x18(%rsp)
31: 48 83 c6 02 add $0x2,%rsi
35: 48 89 74 24 10 mov %rsi,0x10(%rsp)
3a: 48 83 c2 03 add $0x3,%rdx
3e: 48 89 54 24 08 mov %rdx,0x8(%rsp)
43: 48 8d 74 24 10 lea 0x10(%rsp),%rsi
48: 48 8d 7c 24 18 lea 0x18(%rsp),%rdi
4d: b8 00 00 00 00 mov $0x0,%eax
52: e8 00 00 00 00 callq 57 <P+0x35>
57: 48 89 c3 mov %rax,%rbx
5a: 48 8d 74 24 08 lea 0x8(%rsp),%rsi
5f: 48 8d 7c 24 10 lea 0x10(%rsp),%rdi
64: b8 00 00 00 00 mov $0x0,%eax
69: e8 00 00 00 00 callq 6e <P+0x4c>
6e: 48 89 c5 mov %rax,%rbp
71: 48 8d 74 24 18 lea 0x18(%rsp),%rsi
76: 48 8d 7c 24 08 lea 0x8(%rsp),%rdi
7b: b8 00 00 00 00 mov $0x0,%eax
80: e8 00 00 00 00 callq 85 <P+0x63>
85: 48 01 eb add %rbp,%rbx
88: 48 01 d8 add %rbx,%rax
8b: 48 83 c4 20 add $0x20,%rsp
8f: 5b pop %rbx
90: 5d pop %rbp
91: c3 retq
- Find the size of the stack in bytes.
- Identify the assembly statement(s) that allocate and free the local stack.
- Identify which local values get stored in callee-saved registers.
- Identify which local values get stored on the stack.
- Explin why the program could not sotre all of the local values in callee-saved registers.
- For a C function having the general structure, GCC generates the assembly below (See Figure 3.35 and practice problem 3.35 of page 254):
long unknown(unsigned long x) {
if (___________)
return _________;
unsigned long nx = _____________________;
long rv = unknown(x);
return ___________________;
}
0000000000000000 <unknown>:
0: 48 85 ff test %rdi,%rdi
3: 75 06 jne b <unknown+0xb>
5: b8 00 00 00 00 mov $0x0,%eax
a: c3 retq
b: 53 push %rbx
c: 48 89 f8 mov %rdi,%rax
f: 48 83 f0 01 xor $0x1,%rax
13: 83 e0 01 and $0x1,%eax
16: 48 89 c3 mov %rax,%rbx
19: 48 d1 ef shr %rdi
1c: e8 00 00 00 00 callq 21 <unknown+0x21>
21: 48 01 d8 add %rbx,%rax
24: 5b pop %rbx
25: c3 retq
What value does unknown() store in the calleed-saved register %rbx?
Fill in the missing expressions in the C code shown above.
Hint: "unknown 31" returns 0 while "unknown -31" returns 4.
- Given the array declarations, fill in the following table describing the element size, the total size, and the address of element i for each of these arrays (see practice problem 3.36 for reference).
| Array declaration | Element size | Total size | Start address | Element i |
(a) | char r[4]; | | | x_r | |
(b) | char *s[4]; | | | x_s | |
(c) | short t[5]; | | | x_t | |
(d) | short *u[5]; | | | x_u | |
(e) | short **v[3]; | | | x_v | |
(f) | int w[4]; | | | x_w | |
(g) | long *x[5]; | | | x_x | |
(h) | double *y[6]; | | | x_y | |
- Do practice problem 3.37 of page 258 with the expressions shown below, where x_s, the address of short integer array S and long integer index i are stored in registers %rdx and %rcx, respectively while the result should be stored in register %rax if it is a pointer and register element %ax if it has data type short:
| Expression | Type | Value | Assembly code |
(a) | S[2] | | | |
(b) | S+2 | | | |
(c) | &S[i] | | | |
(d) | S[2*i+1] | | | |
(e) | S+i-2 | | | |
(f) | *(S+i-2) | | | |
(g) | S+(++i)+2 | | | |
(h) | *(S+(i++)+2) | | | |
(i) | *S-- | | | |
(j) | *(S--) | | | |