接着上面的c++分析,我們來實現這個斐波那契函數,首先,我們要知道程序需要我們與之交互,也就是說我們要告訴程序n是多少,在c++裏你可能很熟悉,就是cin或者cout可以交互,其實在mips彙編語言裏面,情況也是差不多的,SPIM仿真一個I/O設備:一個內存映射的控制檯(console),在這個控制檯中可以讀和寫字符,而SPIM可以通過系統調用指令即syscall提供一小組類似操作系統的服務,爲了請求一個服務,一個程序加載系統調用代碼到寄存器$v0,將參數加載到寄存器$a0-$a3,系統調用將返回值放到$v0,那我們下面通過一個簡單的例子說明:
.text main: li $v0,5 syscall move $a0,$v0 li $v0,1 syscall jal $ra
.text說明下面是代碼段,與之對應的是.data,表明是程序所需要的數據,下面會看到相應的應用,這裏面進入到main函數,首先把5取到$v0,調用的是read_int服務,那麼我們把這個整數讀取並且放在$v0寄存器中了,再輸出可以用1調用print int服務。
那麼這簡單的鋪墊解決了一些基本的問題,我們繼續分析!
手頭上剛好有一份別人的遞歸代碼,貼上來僅供參考:
.text main: subu $sp, $sp, 32 #set up main's stack frame: sw $ra, 28($sp) sw $fp, 24($sp) addu $fp, $sp, 32 ##Get n from the user, put into $a0. li $v0, 5 #load syscall read_int into $v0 syscall #make the syscall move $a0, $v0 #move the number read into $t0 jal prone #call prone move $a0, $v0 li $v0, 1 #load syscall print_int into $v0 syscall #make the syscall la $a0, newline li $v0, 4 syscall #make the syscall li $v0, 10 #10 is the exit syscall. syscall ##prone--(project one) ##Registers used: ## $a0, -initiallly n. ## $t0, -parameter n. ## $t1, -prone(n - 1). ## $t2, -prone(n - 2). ## $t3, -prone(n - 3). .text prone: bgt $a0, 2, prone_recurse subu $v0, $a0, $zero jr $ra prone_recurse: #the recursive case: subu $sp, $sp, 32 #frame size = 32 sw $ra, 28($sp) sw $fp, 24($sp) addu $fp, $sp, 32 move $t0, $a0 #get n from caller. sw $t0, 20($sp) #preserve n. sub $a0, $t0, 1 #compute prone(n -1) jal prone move $t1, $v0 #t1 = prone(n-1) lw $t0, 20($sp) #restore $t0 sw $t1, 16($sp) #preserve $t1. sub $a0, $t0, 2 #compute prone(n -2) jal prone move $t2, $v0 #t1 = prone(n-2) lw $t1, 16($sp) #restore $t1. lw $t0, 20($sp) sw $t2, 12($sp) #preserve $t2 sub $a0, $t0, 3 #compute prone(n -3) jal prone move $t3, $v0 #t2 = prone(n - 3) lw $t2, 12($sp) #restore $t2. lw $t1, 16($sp) mul $t4, $t3, 3 sll $t5, $t2, 1 add $t4, $t4, $t5 add $v0, $t4, $t1 lw $ra, 28($sp) lw $fp, 24($sp) addu $sp, $sp, 32 jr $ra ##data for prone.s: .data newline: .asciiz"\n" ##end of prone.s jr $ra