219 lines
6.0 KiB
Plaintext
219 lines
6.0 KiB
Plaintext
#show link: set text(blue)
|
||
#set text(font: "Calibri")
|
||
#show raw: set text(font: "Fira Code")
|
||
#set table.cell(breakable: false)
|
||
#set table(stroke: (x, y) => (
|
||
left: if x > 0 {
|
||
.1pt
|
||
},
|
||
top: if y == 1 {
|
||
0.5pt
|
||
} else if y > 1 {
|
||
0.1pt
|
||
},
|
||
))
|
||
|
||
#set page(margin: (y: .5in, x: .5in))
|
||
#let solve(solution) = {
|
||
block(
|
||
outset: 3pt,
|
||
inset: 3pt,
|
||
stroke: blue + .3pt,
|
||
fill: rgb(0, 149, 255, 15%),
|
||
radius: 4pt,
|
||
)[#solution]
|
||
}
|
||
|
||
#let solvein(solution) = {
|
||
let outset = 3pt
|
||
h(outset)
|
||
box(
|
||
outset: outset,
|
||
stroke: blue + .3pt,
|
||
fill: rgb(0, 149, 255, 15%),
|
||
radius: 4pt,
|
||
)[#solution]
|
||
}
|
||
|
||
#let note(content) = {
|
||
block(
|
||
outset: 3pt,
|
||
inset: 3pt,
|
||
stroke: luma(20%) + .3pt,
|
||
fill: luma(95%),
|
||
radius: 4pt,
|
||
)[#content]
|
||
}
|
||
|
||
#let notein(content) = {
|
||
let outset = 3pt
|
||
h(outset)
|
||
box(
|
||
outset: outset,
|
||
stroke: luma(20%) + .3pt,
|
||
fill: luma(95%),
|
||
radius: 4pt,
|
||
)[#content]
|
||
}
|
||
|
||
#align(center)[
|
||
= CS 3843 Computer Organization
|
||
HW 9\
|
||
#underline[Price Hiller] *|* #underline[zfp106]
|
||
]
|
||
#line(length: 100%, stroke: .25pt)
|
||
|
||
|
||
1. [24 points] The disassembled code for two functions `first` and `last` is shown below, along with the code for a call of `first` by function `main`:
|
||
#image("./assets/q-1-code.png")
|
||
|
||
Each of these instructions is given a label. Starting with the calling of `first(10)` by `main`, fill in the following table to trace the instruction execution through to the point where the program returns back to `main`.
|
||
|
||
#solve(
|
||
table(
|
||
column-gutter: auto,
|
||
columns: 9,
|
||
align: (left, left, left, center, center, center, center, center, left),
|
||
stroke: (x, y) => {
|
||
let out = (left: none, right: none, top: none, bottom: none)
|
||
|
||
if (y == 1) {
|
||
out.top = 1.5pt + black
|
||
} else {
|
||
if (x == 0) {
|
||
out.right = .7pt + black
|
||
} else if (x == 1) {
|
||
out.left = .7pt + black
|
||
} else {
|
||
out.left = .7pt + blue
|
||
}
|
||
out.bottom = .7pt + blue
|
||
}
|
||
|
||
if (x == 3 or x == 8) {
|
||
out.left = 1.0pt + black
|
||
}
|
||
|
||
if (x == 0) {
|
||
out.left = none
|
||
}
|
||
out
|
||
|
||
},
|
||
table.header(
|
||
table.cell(
|
||
colspan: 3,
|
||
align: center,
|
||
[Instruction],
|
||
),
|
||
table.cell(
|
||
colspan: 5,
|
||
align: center,
|
||
[State values (at beginning)],
|
||
),
|
||
table.cell([]),
|
||
[Label],
|
||
[PC],
|
||
[Instruction],
|
||
[%rdi],
|
||
[%rsi],
|
||
[%rax],
|
||
[%rsp],
|
||
[\*%rsp],
|
||
[Description],
|
||
table.hline(stroke: 1.5pt),
|
||
),
|
||
|
||
[`M1`], [`0x400560`], [`callq`], [`10`], [—], [—], [`0x7fffffffe820`], [—], [Call `first(10)`],
|
||
[`F1`], [`0x400548`], [`lea`], [`10`], [—], [—], [`0x7fffffffe818`], [—], [Load `&x + 1` into `%rsi`],
|
||
[`F2`], [`0x40054c`], [`sub`], [`10`], [`11`], [—], [`0x7fffffffe818`], [—], [Decrement `%rdi` by 1],
|
||
[`F3`], [`0x400550`], [`callq`], [`9`], [`11`], [—], [`0x7fffffffe810`], [—], [Call `last(9, 11)`],
|
||
[`L1`], [`0x400540`], [`mov`], [`9`], [`11`], [—], [`0x7fffffffe808`], [—], [Copy `%rdi` $->$ `%rax`],
|
||
[`L2`], [`0x400543`], [`imul`], [`9`], [`11`], [`9`], [`0x7fffffffe808`], [—], [Multiply `rdi` × `rax`, putting `99` into `rax`],
|
||
[`L3`], [`0x400547`], [`retq`], [`9`], [`11`], [`99`], [`0x7fffffffe810`], [—], [Return to first],
|
||
[`F4`], [`0x400555`], [`repz retq`], [—], [—], [`99`], [`0x7fffffffe818`], [—], [Return to main],
|
||
[`M2`],
|
||
[`0x400565`],
|
||
[`mov`],
|
||
[—],
|
||
[—],
|
||
[`99`],
|
||
[`0x7fffffffe820`],
|
||
[—],
|
||
[Copy the calculated value from `first(10)` (stored in `%rax`) to `%rdx`],
|
||
),
|
||
)
|
||
|
||
#pagebreak()
|
||
2. [24 points] Consider a function `P`, which generates local values, named `a0`-`a8`. It then calls function `Q` using these generated values as arguments. GCC produces the following code for the first part of `P`:
|
||
|
||
#align(left)[
|
||
#image("./assets/q-2-code.png", width: 40%)
|
||
]
|
||
|
||
#enum(
|
||
numbering: "A.",
|
||
[
|
||
Identify which local values get stored in callee-saved registers.
|
||
#solve[
|
||
Local values are stored in callee-saved registers from lines 9 to 14, those being:
|
||
#block(inset: (left: 1em, bottom: .5em))[
|
||
- `%rdi -> %rbx` (`a0`)
|
||
- `%1(rdi) -> %r15` (`a1`)
|
||
- `%2(rdi) -> %r14` (`a2`)
|
||
- `%3(rdi) -> %r13` (`a3`)
|
||
- `%4(rdi) -> %r12` (`a4`)
|
||
- `%5(rdi) -> %rbp` (`a5`)
|
||
]
|
||
]
|
||
],
|
||
[
|
||
Identify which local values get stored on the stack.
|
||
#solve[
|
||
The first local value that is stored on the stack is `a6` via the indirection of `leaq 6(%rdi), %rax` & `movq %rax, (%rsp)`.
|
||
|
||
The second local value is `a7` via `leaq 7(%rdi), %rdx` & `movq %rdx, 8(%rsp)`.
|
||
]
|
||
],
|
||
[
|
||
Explain why the program could not store all of the local values in callee saved registers.
|
||
#solve[
|
||
There are no more callee-saved registers available. It must store the last two values on the stack as that's largely the only place to put them (unless we want to start doing some heap allocations).
|
||
]
|
||
],
|
||
)
|
||
|
||
#pagebreak()
|
||
|
||
3. [16 points] For a C function having the general structure:
|
||
|
||
#align(left)[
|
||
#image("./assets/q-3-code.png", height: 50%)
|
||
]
|
||
#enum(
|
||
numbering: "A.",
|
||
[
|
||
What value does `rfun` store in the callee-saved register `%rbx`?
|
||
#solve[
|
||
`rfun` stores `x` in `%rbx`, see line 3 of the assembly code.
|
||
|
||
Alternatively, we can say that `rfun` stores `%rdi` in `%rbx`.
|
||
]
|
||
],
|
||
[
|
||
Fill in the missing expressions in the C code shown above.
|
||
#solve[
|
||
#note[It's odd that we have the `movl $0, %eax` _before_ the test instructions... definitely sent me for a loop.]
|
||
```c
|
||
long rfun (unsigned long x) {
|
||
if (x == 0)
|
||
return 0;
|
||
unsigned long nx = x >> 2;
|
||
long rv = rfun(nx);
|
||
return rv + x;
|
||
}
|
||
```
|
||
]
|
||
],
|
||
)
|