0
.data

.text
.globl main

main:
li a0, 5

jal fact

li a7, 1
ecall
li a7, 10
ecall

fact:
li t0, 2
bge a0, t0, else 
li a0, 1
jr ra

else:
addi sp, sp, -8
sw a0, 4(sp)
sw ra, 0(sp)
addi a0, a0, -1
jal fact
lw t0, 4(sp)
mul a0, a0, t0
lw ra, 0(sp)
addi sp, sp, 8
jr ra

Could I have a detailed explanation of what happens in each cycle? Thanks.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • These are simple instructions. Comment each one and/or draw a flowchart. Which one is unclear? – Jester Nov 29 '22 at 12:25
  • I didn't understand saving the integers on the stack, the first time it saves the 5, then the 4, then 3 until the 2. It's not clear to me in which position of the stack they are saved. – Emanuele Iandolo Nov 29 '22 at 12:48
  • It's recursion. Always saving the current argument from `a0` to the stack at `4(sp)` so that after the recursive call returns the result can be multiplied with it. – Jester Nov 29 '22 at 12:56
  • 1
    Each recusive call allocates new stack space. So each of those 5,4,3... are saved at a different location/address in the stack, though always at 4 relative to the current stack pointer. Allocation/deallocation is done by merely moving the stack pointer, i.e. changing the number held in `sp` register. – Erik Eidt Nov 29 '22 at 14:34
  • On the way "down" in the recursion, the larger items are "pushed" onto the stack for later use. On the way back "up" in the recursion, the larger items are used from the stack, and then popped. Transition between "down" and "up" happens here when the terminal condition is reached, therefore "down" stops, and so "up" starts. – Erik Eidt Nov 29 '22 at 20:35
  • @adrianmcmenamin, the `jr ra` instructions (aka `ret` in simpler form) are return from subroutine/function, rather than recursive calls: the `jal fact` is *the* recursive call. – Erik Eidt Dec 06 '22 at 20:22
  • ah yes @Erik you are right - as it's a proxy for jalr zero, 0(ra) – adrianmcmenamin Dec 07 '22 at 15:01

0 Answers0