MIPS——有符號乘法


在無符號乘法基礎上改進的有符號乘法。如有錯誤請指正。(debug弄死我了)

init:
    li $v0 5                    #輸入被乘數$a0
    syscall
    addu $a0 $v0 $0
    li $v0 5                    #輸入乘數$a1
    syscall
    addu $a1 $v0 $0
    li $v1 0                    #$v1存儲積的高32位
    li $v0 0                    #$v0存儲積的低32位
    li $t2 0                    #$t2記錄執行次數
    andi $t1 $a0 0x80000000     #判斷被乘數是否為負數 若為負數則進行符號擴展
    beq  $t1 0   posi           
                                #$s0存儲被乘數的高32位
    li $s0 0xffffffff           #符號擴展        
    j  mull
    
 posi:
    li $s0 0   
    
mull:
    andi $t1 $a1 1          #判斷乘數的最后一位是否為1
    beq  $t1 0   shift      #最后一位不是1 進入移位部分
    addu $v1 $v1 $s0        #積的高32位=積的高32位+被乘數的高32位
    addu $v0 $v0 $a0        #積的低32位=積的低32位+被乘數的低32位
    sltu $t1 $v0 $a0        #判斷低32位相加時是否溢出 若溢出則和必定小於乘數
    beq  $t1 $0  shift      #沒有溢出 進入移位部分
    addiu $v1 $v1 1         #發生溢出 積的高32位加1
    
shift:
    srl  $a1 $a1 1          #乘數右移一位
    sll  $s0 $s0 1          #先將被乘數的高32位左移一位
    andi $t1 $a0 0x80000000 #判斷被乘數的低32位最高位是否為1
    sll  $a0 $a0 1          #被乘數的低32位左移一位
    beq  $t1 0   ad         #被乘數的低32位最高位不是1 進入自增部分 
    addiu $s0 $s0 1         #被乘數的低32位最高位是1 高32位加1
    
ad:
    addi $t2 $t2 1          #執行次數加1
    slti $t1 $t2 31         #判斷是否已經執行31次
    beq  $t1 1   mull       #還未執行31次 進入下一次循環
    
check:                      #若乘數一開始為負數 既符號位為1 那么最后還要加上被乘數的補碼
    beq  $a1 0  print1      #乘數為正數 直接進入打印部分
    nor  $s0 $s0 $s0        #被乘數的高32位取反
    nor  $a0 $a0 $a0        #被乘數的低32位取反
    addiu $a0 $a0 1         #取反再加1得到補碼
    sltiu $t0 $a0 1         #判斷溢出
    add  $s0 $s0 $t0        #高32位加上溢出位
    addu $v1 $s0 $v1        #積的高32位=積的高32位+被乘數的高32位
    addu $v0 $v0 $a0        #積的低32位=積的低32位+被乘數的低32位
    sltu $t1 $v0 $a0        #判斷低32位相加時是否溢出 若溢出則和必定小於乘數
    beq  $t1 $0  print1     #沒有溢出 進入打印部分
    addiu $v1 $v1 1         #發生溢出 積的高32位加1
    
print1:
    move $s0 $v0            #先將積的低32位轉移
    move $a0 $v1            #將積的高32位放到$a0
    beq  $a0 0 print2       #如果積的高32位為0或-1 進入低32位輸出部分
    beq  $a0 0xffffffff print2
    li   $v0 1              #打印積的高32位
    syscall
    
print2:
    move $a0 $s0            #將積的低32位放到$a0
    li   $v0 1              #打印積的低32位
    syscall
    
exit:
    li   $v0 10             #退出程序
    syscall
    
    
    
    
    

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM