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_s and last_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)