Multiplication using Logical shifts in MIPS assembly

早过忘川 提交于 2020-01-02 18:03:38

问题


Can someone please give me pointers on how I can go about making a code that multiplies using shifts in MIPS assembly? I don't understand how having a number 2^n can help me multiply using an odd multiplicand


I currently have this code, I'm trying to make a calculator

.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"

回答1:


Shifting a number n bits left multiples the number by 2n. For example n << 3 = n*2^3 = n*8. The corresponding instruction is

SLL $s1, $s2, 1

To multiply any number you can split the number into sum of power of 2s. For example:

n*10 = n*8 + n*2 = n << 3 + n << 1

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

You can also use a subtraction if it's faster

n*15 = n*16 - n = n << 4 - n

SLL $t1, $s2, 4
SUB $s1, $t1, $s2



回答2:


i dont understand how having a number 2^n can help me multiply using an odd multiplicand

Here are some examples for when one of the factors is constant:

// 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

EDIT: Since you've now explained that both the multipler and multiplicand are variable (which I don't feel was clear in your original question), I'm updating my answer with an explanation of how to go about doing the multiplication:

The algorithm works like this:

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

And a MIPS assembly implementation could look like this:

# 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

Note that I use a loop to make things simpler. But you could unroll the loop if you wanted to (i.e. duplicate the loop body)




回答3:


to multiply a number by 2, you just shift it to the left. To divide it by to, shift it to the right.

Example : 2 = 10 (binary) -> 2*2 = 4 -> 4 = 100 (binary) = SLL(2) = SLL(10) (binary)

The MIPS instruction would be : SLL $s1, $s2, 1



来源:https://stackoverflow.com/questions/18812319/multiplication-using-logical-shifts-in-mips-assembly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!