【问题标题】:Multiplication by a power of 2 using Logical shifts in MIPS assembly使用 MIPS 汇编中的逻辑移位乘以 2 的幂
【发布时间】:2013-09-15 12:22:40
【问题描述】:

有人可以指点我如何使用 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"

【问题讨论】:

    标签: assembly mips multiplication bit-shift


    【解决方案1】:

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

    SLL $s1, $s2, 3       # $s1 = $s2 * 8   shift left by 3 bit-positions
    

    要乘以任何数字,您可以将数字拆分为 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
      

    【讨论】:

    • 谢谢,那么我如何得到最终答案说 n = 3
    • n = 3 但 n 乘以多少?无论如何,这是一个简单的数学,你可以自己计算出来
    • 我知道如何通过迭代加法来做到这一点,同时使用一个数字作为计数器,我要问的是:n 是否可能决定你执行多少班次?并且是一种在 mips 中自动将数字分解为 2 次方的方法,对不起,我真的很困惑!
    • 在我的示例中,n 是一个变量乘数乘以一个常数乘数。移位由乘数确定。如果您的意思是 n 是乘数,则移位由 n 中的 1 位确定,例如 multiply in binary
    【解决方案2】:

    我不明白数字 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
    

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

    【讨论】:

    • 我可以不使用任何循环结构,但可以使用 sub,添加 e.t.c
    • 不需要循环。正如我在示例中所展示的,它可以通过移位、添加和替换来完成。
    • :( 我真的不明白这个“ temp = x
    • &lt;&lt; 是左移,即 MIPS 汇编中的 sll 指令。 x 表示保存要相乘的原始值的寄存器,temp 表示您用作临时寄存器(任何寄存器)。
    【解决方案3】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-02
      • 2016-03-13
      • 1970-01-01
      • 1970-01-01
      • 2013-02-27
      相关资源
      最近更新 更多