5.139 · exercise

Draw the frame: a recursive call

The program is paused two calls deep in sum_to: main called sum_to(4), which called sum_to(3). Draw the running call's frame.

Every call to sum_to builds a frame of its own with the same layout, and fp points at the frame of the call that is running. Three frames are on the stack at the pause; draw the newest one, in bytes from its fp.

What is checked

  • the frame's size in bytes
  • the offsets from fp of n_s and part_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

// Add 1 + 2 + ... + n with a function that calls itself.define(fp, x29)define(lr, x30)define(n_r, w19)n_size = 4                                      // intpart_size = 8                                   // longn_s = 16part_s = (n_s + n_size + 7) & -8                // a long starts on a multiple of 8alloc = -(part_s + part_size) & -16dealloc = -alloc.datafmt_out:    .string "sum to %d = %ld\n".text// sum_to(w0 = n) -> x0 = 1 + 2 + ... + n        .balign 4        .global sum_tosum_to:        stp     fp, lr, [sp, alloc]!        mov     fp, sp        str     w0, [fp, n_s]                   // n has to outlive the call below        str     xzr, [fp, part_s]               // nothing added yet        cmp     w0, 1 (paused before this line)        b.le    st_base                         // sum_to(1) is 1        sub     w0, w0, 1        bl      sum_to                          // x0 = sum_to(n - 1)        str     x0, [fp, part_s]        ldrsw   x9, [fp, n_s]        ldr     x10, [fp, part_s]        add     x0, x10, x9                     // n + sum_to(n - 1)        b       st_donest_base:        ldrsw   x0, [fp, n_s]                   // n itselfst_done:        ldp     fp, lr, [sp], dealloc        ret        .balign 4        .global mainmain:        stp     fp, lr, [sp, -16]!        mov     fp, sp        mov     n_r, 4        mov     w0, n_r        bl      sum_to                          // x0 = sum_to(4)        mov     x2, x0        ldr     x0, =fmt_out        mov     w1, n_r        bl      printf        mov     w0, 0        ldp     fp, lr, [sp], 16        ret

Paused before line 30 runs, the 2nd time the program gets there.

the frame at the pause

  • part_s
  • n_s
  • saved lr (x30)
  • saved fp (x29)