5.138 · exercise
Draw the frame: int and long locals
The program is paused inside tally, which keeps an int, a long and another int in its frame. Fill in where each one sits.
Each local's offset is an equate at the top of the program, built from the one before it. A long starts on a multiple of 8, so sum_s rounds up past a gap, and alloc rounds the whole frame up to a multiple of 16. Work each number out by hand and give it in bytes from fp, the way the frames view counts them.
What is checked
- the frame's size in bytes
- the offsets from fp of
count_s,sum_sandlast_s - 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
// Count the odd values in a list, add them up, and keep the last one found.define(fp, x29)define(lr, x30)count_size = 4 // intsum_size = 8 // longlast_size = 4 // intcount_s = 16sum_s = (count_s + count_size + 7) & -8 // a long starts on a multiple of 8last_s = sum_s + sum_sizealloc = -(last_s + last_size) & -16dealloc = -alloc.datavalues: .word 12, 7, 30, 5, 19, 8fmt_out: .string "%d odd values, sum %ld, last %d\n".text// tally(x0 = values, w1 = n): prints how many are odd, their sum and the last one .balign 4 .global tallytally: stp fp, lr, [sp, alloc]! mov fp, sp str wzr, [fp, count_s] // count = 0 str xzr, [fp, sum_s] // sum = 0 str wzr, [fp, last_s] // last = 0 mov x9, x0 // copy the arguments out of x0 and w1 mov w10, w1 mov w11, 0 // index b ta_testta_loop: ldr w12, [x9, w11, SXTW 2] // w12 = values[index] tst w12, 1 b.eq ta_next // even: skip it ldr w13, [fp, count_s] add w13, w13, 1 str w13, [fp, count_s] // count = count + 1 sxtw x14, w12 ldr x13, [fp, sum_s] add x13, x13, x14 str x13, [fp, sum_s] // sum = sum + value str w12, [fp, last_s] // last = valueta_next: add w11, w11, 1ta_test: cmp w11, w10 b.lt ta_loop ldr x0, =fmt_out (paused before this line) ldr w1, [fp, count_s] ldr x2, [fp, sum_s] ldr w3, [fp, last_s] bl printf ldp fp, lr, [sp], dealloc ret .balign 4 .global mainmain: stp fp, lr, [sp, -16]! mov fp, sp ldr x0, =values mov w1, 6 bl tally mov w0, 0 ldp fp, lr, [sp], 16 ret
Paused before line 55 runs.
the frame at the pause
- last_s
- sum_s
- count_s
- saved lr (x30)
- saved fp (x29)