如何在不使用内置指令的情况下在MIPS汇编中实现乘法和除法?

时间:2012-03-21 04:57:08

标签: mips

好的,这是问题所在。我不得不写一个MIPS程序,它从用户那里获得了2个输入数字。然后,我必须编写一个代码,输出用户输入的2个数字的乘积,商和余数。

现在,这很简单。但是,我没有意识到我们不能在程序中使用乘法和除法操作数。现在我不知道该怎么做因为我对如何在没有乘法和除法操作数的情况下这样做感到困惑。我只在整个程序中使用它两次,它工作正常,但我的教授不接受它,现在我很伤心。任何帮助,将不胜感激。谢谢

这是我的代码

# Given positive integers a and b, output a/b and a%b.
  .data
str1: .asciiz "Enter a: "
str2: .asciiz "Enter b: "
str3: .asciiz "a/b = "
str4: .asciiz "a%b = "
str5: .asciiz "a*b = "
newline: .asciiz "\n"
  .text

main: li   $v0, 4            # system call code for print_string
  la   $a0, str1         # address of str1
  syscall                # print str1

#get the first number from user, put it into $s0

li   $v0, 5            # system call code for read_int
  syscall                # read an integer into $v0 from console
  add  $s0, $v0, $zero   # copy $v0 into $s0 (a)


#read print_string for str2
li   $v0, 4            # system call code for print_string
  la   $a0, str2         # address of str1
  syscall                # print str1

# get second number from user, put it into $t1  
li  $v0, 5      #load syscall for read_int
syscall         #make the syscall
move $s1, $v0       #move the number read into $s1(b)

#DO THE CALCULATIONS................................................
div $s0, $s1        #diving $s0 by $s1
mflo    $t0         #storing value of lo(quotient) in
                #register $t0
mfhi    $t1         #storing value of hi(remainder) in
                #register $t1

mult $s0, $s1
mflo $t2


li $v0,1
move $a0, $t2
syscall

li $v0,4
la $a0, str5
syscall

#read print_string for str3
li   $v0, 4            # system call code for print_string
  la   $a0, str3         # address of str1
  syscall                # print str1   

#print a/b
li  $v0, 1      #load syscall print_int into $v0
move $a0, $t0      #move the number to print into $t2
syscall
# read print string for str4
li $v0, 4
    la $a0, str4
    syscall
# print remainder
li $v0, 1
move $a0, $t1
syscall

#end of program
li  $v0, 10     #system call code for exit
syscall

3 个答案:

答案 0 :(得分:8)

您正在寻找的是按位乘法/除法。

我不确定我能简洁地总结一下,但在这里我举个例子:

To Multiply

假设您希望将数字6乘以数字5 如果a =数字6,则(简化为8位)这是:
a=00000110

如果b =数字5,则(简化为8位)这是:
b=00000101

要将这些数字相乘,您需要在数字下方移动最接近的2的倍数,然后添加。

例如,5的最接近的2的倍数是4,也就是说它是2 ^ 2;
所以我们按位向左移a(数字6)2次:
a << 2
现在使它成为00011000

这意味着我们现在乘以4;现在将其乘以5,我们只需再次添加a

     00011000  
    +00000110  
    =00011110  
    =30 (base 10)

这是6 * 5.

让我们再试一次12 * 11 最接近11的2的倍数是8(2 ^ 3)。这意味着我们需要按顺序将数字12移位3次,然后再将其添加到自身3次。

    00001100 = 12
    //Let's bitshift by 3
    01100000 = 96
    //Let's add 12 3 times
    01100000
   +00001100
   =01101100 = 108
   +00001100
   =01111000 = 120
   +00001100
   =10000100 = 132 = 12*11

分割

将12除以11,你走另一条路;从132减去12,减去3次,然后向右减移3次(除以8)

相关资源

这是我现在能做的最好的事情;如果您想要更多,使用C中的相关算法,请查看http://www.programmersheaven.com/mb/CandCPP/295363/295363/bitwise-multiplication--division/

如果您希望扩展此任何答案,请在下方发表评论;

P.S。我已经向你展示了两个素数(令人讨厌)的例子,但如果你得到像12这样的数字呢? 从逻辑上讲,根据我所说的,2的最接近的倍数是8(2 ^ 3),所以你必须将第3位移位,然后将4加12加入。

但是如果你做数学,你会发现12实际上是=(2 ^ 3 + 2 ^ 2)...这意味着你可以得到(12 <&lt; 3)(那是12位左移) 3次)​​,然后将其添加到(12 <2)(剩下12位换档2次)......魔法!

答案 1 :(得分:2)

尝试使用乘法算法: 这是Boothe算法的MIPS实现: http://code.google.com/p/mips-booth-multiplication/source/browse/trunk/booth.asm?r=9

答案 2 :(得分:0)

来自Wikipedia entry on Multiplication

“因为按整数进行缩放的结果可以被认为是由原始的一些副本组成,所以可以通过重复添加来计算大于1的整数产品”

换句话说,要将 a * b 相乘,您可以将 a 一起添加 b 次。

你在评论中提到的策略(比特转换)很有意思 - 可能更有效,但绝对要复杂得多。

类似的策略适用于除法/余数。