3

有人可以给我一些指导,告诉我如何使用 MIPS 程序集中的移位来制作一个乘法的代码吗?我不明白数字 2^n 如何帮助我使用奇数被乘数进行乘法运算


我目前有这个代码,我正在尝试制作一个计算器

.text

li  $v0, 4 
la  $a0, ask_1
syscall

li  $v0,5
syscall
move    $s1, $v0


li  $v0, 4
la  $a0, ask_2
syscall

li  $v0,5
syscall
move    $s2, $v0

#sll    $s2, $s2, 3     #$s2 * $s2^3 = result
srl $s2, $s2, 1

li  $v0, 1
la  $a0, ($s2)
syscall


.data

ask_1:  .asciiz     "Enter Multiplier\n"
ask_2:  .asciiz     "Enter Multiplicand\n"
result: .asciiz         "The Answer is:\n"
4

3 回答 3

6

将数字左移 n 位会使该数字乘以 2 n。例如n << 3 = n*2³ = n*8. 对应的指令是

SLL $s1, $s2, 1

要乘以任何数字,您可以将数字拆分为 2 的幂的总和。例如:

  • n*10 = n*8 + n*2 = (n << 3) + (n << 1)

      SLL $t1, $s2, 1
      SLL $t2, $s2, 3
      ADD $s2, $t1, $t2
    

如果速度更快,您也可以使用减法

  • n*15 = n*16 - n = (n << 4) - n

      SLL $t1, $s2, 4
      SUB $s1, $t1, $s2
    
于 2013-09-15T12:59:17.727 回答
3

我不明白数字 2^n 如何帮助我使用奇数被乘数进行乘法运算

以下是其中一个因素恒定时的一些示例:

// x *= 3
temp = x << 1  // x*2
x = temp + x   // x*2 + x

// x *= 10
temp = x << 1  // x*2
x = temp << 2  // x*8
x = temp + x   // x*2 + x*8

// x *= 15
temp = x << 4  // x*16
x = temp - x   // x*16 - x

编辑:既然你现在已经解释了乘数和被乘数都是可变的(我觉得你原来的问题不是很清楚),我正在更新我的答案,解释如何进行乘法:

该算法的工作原理如下:

result = 0
shift = 0
foreach (bit in multiplicand) {
    if (bit == 1) {
        result += multiplier << shift
    }
    shift += 1
}

MIPS 汇编实现可能如下所示:

# In: $s1 = multiplier, $s2 = multiplicand
# Out: $t0 = result
move $t0,$zero      # result
mult_loop:
    andi $t2,$s2,1
    beq $t2,$zero,bit_clear
    addu $t0,$t0,$s1  # if (multiplicand & 1) result += multiplier << shift
bit_clear:
    sll $s1,$s1,1     # multiplier <<= 1
    srl $s2,$s2,1     # multiplicand >>= 1
    bne $s2,$zero,mult_loop

请注意,我使用循环使事情变得更简单。但如果你愿意,你可以展开循环(即复制循环体)

于 2013-09-15T13:00:19.673 回答
0

要将一个数字乘以 2,只需将其向左移动即可。要将其除以,请将其向右移动。

示例:2 = 10(二进制)-> 2*2 = 4 -> 4 = 100(二进制)= SLL(2) = SLL(10)(二进制)

MIPS 指令为:SLL $s1, $s2, 1

于 2013-09-15T12:41:01.633 回答