.file "test_asm.S" .section .rodata .data text: .asciz "Hallo, Welt!" space: .asciz " " crlf: .asciz "\n" .text .globl main main: .set noreorder move $t0, $0 loop: la $a0, text li $v0, 4 syscall la $a0, space li $v0, 4 syscall move $a0, $t0 li $v0, 1 syscall la $a0, crlf li $v0, 4 syscall j fibo addiu $t0, 1 nop .set reorder .data in_string: .asciiz "Input a positive integer:\n\n" out_string: .asciiz "The Fibonacci number is:\n\n" .text fibo: addu $fp,$sp,28 # print out prompt li $v0, 4 # system call code for printing string = 4 la $a0, in_string # load address of string to be printed into $a0 syscall # call operating system to perform print operation # read integer into $s0 li $v0, 5 # system call code for read integer = 5 syscall # call operating system move $s0, $v0 # value read from keyboard returned in register $v0; transfer to $s0 sw $s0,($sp) # push argument for Fib on stack addi $sp,$sp,-4 # and decrement stack pointer jal Fib # jump to subroutine addi $sp,$sp,4 # increment stack pointer lw $s1,($sp) # and pop result from stack # print out prompt li $v0, 4 # system call code for printing string = 4 la $a0, in_string # load address of string to be printed into $a0 syscall # call operating system # print out result (stored in $s1) li $v0, 1 # system call code for printing integer = 1 move $a0, $s1 # move integer to be printed into $a0: $a0 = $s1 syscall # call operating system to perform print # exit program li $v0, 10 # system call code for exit = 10 syscall # call operating system # blank line at end to keep SPIM happy! ################################################################################## # Fibonacci subroutine # input: integer n, on stack # output: Fib(n), nth Fibonacci number # description: recursively computes Fib(n) = Fib(n-1) + Fib(n-2), Fib(1) = Fib(2) = 1. # uses: $t0, $t1 ################################################################################## Fib: # procedure prologue: sw $ra,($sp) # save return address on stack, since recursive, addi $sp,$sp,-4 # and decrement stack pointer sw $fp,($sp) # save previous frame pointer on stack addi $sp,$sp,-4 # and decrement stack pointer add $fp,$sp,12 # set frame pointer to point at base of stack frame lw $t0,($fp) # copy argument to $t0: $t0 = n li $t1, 2 bgt $t0,$t1,do_recurse # if argument n >= 2, branch to recursive sequence li $t0, 1 # else set result to 1 (base cases n = 1 and n = 2) b epilogue # branch to end do_recurse: addi $t0,$t0,-1 # $t0 = n-1 sw $t0,($sp) # push argument n-1 on stack addi $sp,$sp,-4 # and decrement stack pointer jal Fib # call Fibonacci with argument n-1 # leave result on stack for now lw $t0,($fp) # re-copy argument to $t0: $t0 = n addi $t0,$t0,-2 # $t0 = n-2 sw $t0,($sp) # push argument n-2 on stack addi $sp,$sp,-4 # and decrement stack pointer jal Fib # call Fibonacci with argument n-2 addi $sp,$sp,4 # increment stack pointer lw $t0,($sp) # and pop result of Fib(n-2) from stack into $t0 addi $sp,$sp,4 # increment stack pointer lw $t1,($sp) # and pop result of Fib(n-1) from stack into $t1 add $t0,$t0,$t1 # $t0 = Fib(n-2) + Fib(n-1); have result epilogue: # procedure epilogue: $t0 holds result addi $sp,$sp,4 # increment stack pointer lw $fp,($sp) # and pop saved frame pointer into $fp addi $sp,$sp,4 # increment stack pointer lw $ra,($sp) # and pop return address into $ra addi $sp,$sp,4 # increment stack pointer # to pop argument (n) from stack (discard) sw $t0,($sp) # push result onto stack addi $sp,$sp,-4 # and decrement stack pointer jr $ra # return to caller ################################################################################## # end of Fibonacci ##################################################################################