MIPS中的精细按位除法算法

时间:2015-02-17 06:48:51

标签: algorithm assembly bit-manipulation mips integer-division

我们的任务是在MIPS中实现精细的按位除法算法。

基本上在精炼程序中,我们将被除数加载到64位寄存器的LO位中,其余部分将累积在HI位中,这些位最初都设置为0。

然后我们只测试HI(我们的余数)> =除数。 如果我们的累积余数目前不是> =除数,我们只需移动整个寄存器并用0填充。这是我们商的开始。当红利位移入HI时,我们最终会遇到HI> 1的情况。 = 除数。然后我们将从HI中减去除数,将整个寄存器向左移,然后用1填充。

简而言之,我们可以简单地继续向左移动所有64位,当HI <1时填充0。除数,从HI中减去除数,当HI> 1时用1填充。 =除数。

在我们的作业中,我们要编写一个程序,从控制台接受两个正数(16位有符号数字),将前者除以后者。

我将除数设为$ t0,其余为$ t3,红利为$ t2。 $ t3​​和$ t2都是16位,它们一起配对成32位寄存器。不知何故,我的程序返回一个非常有趣的商:最不重要的几个位是正确的,但最重要的是总是1;不知怎的,我无法摆脱1,无论我向左移多少位。例如,如果红利是1000,通过向左移动,而不是获得0001 0000,我实际得到10000 - MSB总是1.有人可以看看我的程序并给我一些建议吗?非常感谢!

.data
GETA:           .asciiz "Enter Dividend: "
GETB:           .asciiz "Enter Divisor: "
QT:           .asciiz "Quotient = "
RM:           .asciiz "Remainder = "
NL:             .asciiz "\n"

.text
main:
li $v0, 4             #Prompt for a dividend               
la $a0, GETA                           
syscall                                     

li $v0, 5             #Read dividend from user                   
syscall                              
move $t2, $v0         #dividend in $t2

li $v0, 4             #Prompt for a divisor        
la $a0, GETB                         
syscall     

li $v0, 5             #Read divisor from user                       
syscall                               
move $t0, $v0         #divisor in $t0                   

addi $t4, $zero, 17   #counter
j Loop

Loop:
slt $t1, $t3, $t0     #if remainder < divisor, $t1=1
beq $t1, $zero, subroutine   #remainder >= divisor, $t1=0

#if remainder < divisor
sll $t3, $t3, 1       #shift remainder by to left by 1

andi $t5, $t2, 32768    #get MSB of $t2
bne $zero, $t5, updateRemainder1   #MSB of $t2 is 1
#MSB of $t2 is 0
sll $t2, $t2, 1       #shift dividend to left by 1

addi $t4, $t4, -1     #decrease counter by 1
bne $zero, $t4, Loop
j Exit

subroutine:
sub $t3, $t3, $t0     #subtract divisor from remainder
sll $t3, $t3, 1       #shift remainder by to left by 1

andi $t5, $t2, 32768    #get MSB of $t2
bne $zero, $t5, updateRemainder2   #MSB of $t2 is 1
#MSB of $t2 is 0
sll $t2, $t2, 1       #shift dividend to left by 1
ori $t2, $t2, 1       #fill in LSB of $t2 with a 1

addi $t4, $t4, -1     #decrease counter by 1
bne $zero, $t4, Loop
j Exit

updateRemainder1:
ori $t3, $t3, 1       #set LSB of remainder to 1
sll $t2, $t2, 1       #shift dividend to left by 1  

addi $t4, $t4, -1     #decrease counter by 1
bne $zero, $t4, Loop
j Exit

updateRemainder2:
ori $t3, $t3, 1       #set LSB of remainder to 1
sll $t2, $t2, 1       #shift dividend to left by 1
ori $t2, $t2, 1       #fill in LSB of $t2 with a 1  

addi $t4, $t4, -1     #decrease counter by 1
bne $zero, $t4, Loop
j Exit

Exit:
sub $t2, $t2, 524288
li $v0, 4            #print out output line
la $a0, QT
syscall

li $v0, 1            #print out quotient
move $a0, $t2
syscall

li $v0, 4            #print out new line
la $a0, NL
syscall

li $v0, 4            #print out output line
la $a0, RM
syscall

li $v0, 1            #print out remainder
move $a0, $t3
syscall

li $v0, 10                       
syscall

0 个答案:

没有答案