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 という数値がどのように役立つのか理解できません

要因の 1 つが一定である場合の例を次に示します。

// 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 に答える