Multiplication
Multiplying two registers
Section titled “Multiplying two registers”To multiply two values stored in registers, we use the mul instruction:
mul <destination register>, <source register 1>, <source register 2>For example, to multiply the values in registers x1 and x2, and store the
result in x3, we would write:
mul x3, x1, x2Example program
Section titled “Example program”.textmain: li x1, 6 # Load the value 6 into register x1 li x2, 7 # Load the value 7 into register x2 mul x3, x1, x2 # Multiply x1 and x2, store result in x3
stop: li a7, 10 # Load the exit system call number into register a7 ecall # Make the system call to exit the programThe result:
x3will contain42(since6 * 7 = 42), or2Ain hex!
Specialised multiplication instructions
Section titled “Specialised multiplication instructions”Usually, mul is enough. But if we multiply two large numbers, the result might
not fit into the single 32-bit register that mul ‘returns’.
For this, we need to specify whether our input values are signed or unsigned. We use these instructions:
mulh: get the upper (high) 32 bits of the result of multiplying two signed integersmulhu: get the upper (high) 32 bits of the result of multiplying two unsignedmulhsu: get the upper (high) 32 bits of the result of multiplying a signed integer by an unsigned integer
We can use these instructions in the same way as mul. For example:
li x1, -3000000000li x2, 4000000000mulh x4, x1, x2mulhu x5, x1, x2mulhsu x6, x1, x2Multiplying by an immediate value
Section titled “Multiplying by an immediate value”RISC-V doesn’t have a direct instruction for multiplying a register by an immediate value. There are a few reasons for this, including:
- It keeps the instruction set simpler.
- It’s normally much faster to use a combination of bit-shifts and additions for multiplying by constants, rather than a dedicated multiply instruction.
We’ll get into how to do bitshifts later on!
However, if you need to multiply a register by an immediate value, you can just
first load the immediate value into a register using li, and then use mul.
For example, to multiply the value in x1 by 5, you could write:
li x2, 5 # Load the immediate value 5 into register x2mul x3, x1, x2 # Multiply x1 by x2 (which is 5), store result in x3This will effectively multiply the value in x1 by 5, and store the result in
x3.