5.137 · exercise
Draw the frame: a struct on the stack
The program is paused inside scaled_rect, which keeps an int and a rect record in its frame. Fill in where each field sits.
The record's fields are equates counted from the start of the record (rect_width, rect_height, rect_area), and rect_s is where the record starts in the frame, so a field's offset from fp is rect_s plus the field's own offset. The frames view names each field after the record: rect_s.rect_width is the width field.
What is checked
- the frame's size in bytes
- the offsets from fp of
scale_s,rect_s.rect_width,rect_s.rect_heightandrect_s.rect_area - the offsets from fp of the saved fp and the saved lr
Check runs the program to the pause and compares each number with the frame the emulator draws there. A wrong number shows a hint, never the answer.
the program
// Build a rectangle record on the stack, scaled up, and print it.define(fp, x29)define(lr, x30)// struct rect { int width; int height; long area; }rect_width = 0 // 4 bytesrect_height = 4 // 4 bytesrect_area = 8 // a long starts on a multiple of 8rect_size = 16scale_size = 4 // intscale_s = 16rect_s = (scale_s + scale_size + 7) & -8 // the record holds a long, so it starts on a multiple of 8alloc = -(rect_s + rect_size) & -16dealloc = -alloc.datafmt_out: .string "%d by %d, area %ld\n".text// scaled_rect(w0 = width, w1 = height, w2 = scale): prints the rectangle scaled up .balign 4 .global scaled_rectscaled_rect: stp fp, lr, [sp, alloc]! mov fp, sp str w2, [fp, scale_s] // keep the scale add x9, fp, rect_s // x9 = &rect mul w10, w0, w2 str w10, [x9, rect_width] // rect.width = width * scale mul w11, w1, w2 str w11, [x9, rect_height] // rect.height = height * scale sxtw x12, w10 // widen before the multiply sxtw x13, w11 mul x12, x12, x13 str x12, [x9, rect_area] // rect.area = rect.width * rect.height ldr x0, =fmt_out (paused before this line) ldr w1, [x9, rect_width] ldr w2, [x9, rect_height] ldr x3, [x9, rect_area] bl printf ldp fp, lr, [sp], dealloc ret .balign 4 .global mainmain: stp fp, lr, [sp, -16]! mov fp, sp mov w0, 3 // a 3 by 4 rectangle mov w1, 4 mov w2, 5 // scaled up 5 times bl scaled_rect mov w0, 0 ldp fp, lr, [sp], 16 ret
Paused before line 42 runs.
the frame at the pause
- rect_s.rect_area
- rect_s.rect_height
- rect_s.rect_width
- scale_s
- saved lr (x30)
- saved fp (x29)