Email: Password: Remember Me | Create Account (Free)
16-bit Multiplication


16-bit multiplication is the multiplication of two 16-bit value from another. Such a multiplication results in a 32-bit value.

Programming Tip: In fact, any multiplication results in an answer which is the sum of the bits in the two multiplicands. For example, multiplying an 8-bit value by a 16-bit value results in a 24-bit value (8 + 16). A 16-bit value multiplied by another 16-bit value results in a 32-bit value (16 + 16), etc.

For the sake of example, let's multiply 25,136 by 17,198. The answer is 432,288,928. As with both addition and subtraction, let's first convert the expression into hexadecimal: 6230h x 432Eh.

Once again, let's arrange the numbers in columns as we did in primary school to multiply numbers, although now the grid becomes more complicated. The green section represents the original two values. The yellow section represents the intermediate calculations obtained by multipying each byte of the original values. The red section of the grid indicates our final answer, obtained by summing the columns in the yellow area.

Remember how we did this in elementary school? First we multiply 2Eh by 30h (byte 1 of both numbers), and place the result directly below. Then we multiply 2Eh by 62h (byte 1 of the bottom number by byte 2 of the upper number). This result is lined up such that the right-most column ends up in byte 2. Next we multiply 43h by 30h (byte 2 of the bottom number by byte 1 of the top number), again lining up the result so that the right-most column ends up in byte 2. Finally, we multiply 43h by 62h (byte 2 of both numbers) and position the answer such that the right-most column ends up in byte 3. Once we've done the above, we add each column, with appropriate carries, to arrive at the final answer.

Our process in assembly language will be identical. Let's use our now-familiar grid to help us get an idea of what we're doing:

Thus our first number will be contained in R6 and R7 while our second number will be held in R4 and R5. The result of our multiplication will end up in R0, R1, R2 and R3. At 8-bits per register, these four registers give us the 32 bits we need to handle the largest possible multiplication. Our process will be the following:

  1. Multiply R5 by R7, leaving the 16-bit result in R2 and R3.
  2. Multiply R5 by R6, adding the 16-bit result to R1 and R2.
  3. Multiply R4 by R7, adding the 16-bit result to R1 and R2.
  4. Multiply R4 by R6, adding the 16-bit result to R0 and R1.
We'll now convert the above process to assembly language, step by step.

Step 1. Multiply R5 by R7, leaving the 16-bit result in R2 and R3.

 MOV A,R5 ;Move the R5 into the Accumulator
 MOV B,R7 ;Move R7 into B
 MUL AB   ;Multiply the two values
 MOV R2,B ;Move B (the high-byte) into R2
 MOV R3,A ;Move A (the low-byte) into R3

Step 2. Multiply R5 by R6, adding the 16-bit result to R1 and R2.

 MOV A,R5    ;Move R5 back into the Accumulator
 MOV B,R6    ;Move R6 into B
 MUL AB      ;Multiply the two values
 ADD A,R2    ;Add the low-byte into the value already in R2
 MOV R2,A    ;Move the resulting value back into R2
 MOV A,B     ;Move the high-byte into the accumulator
 ADDC A,#00h ;Add zero (plus the carry, if any)
 MOV R1,A    ;Move the resulting answer into R1
 MOV A,#00h  ;Load the accumulator with  zero
 ADDC A,#00h ;Add zero (plus the carry, if any)
 MOV R0,A    ;Move the resulting answer to R0.

Step 3. Multiply R4 by R7, adding the 16-bit result to R1 and R2.

 MOV A,R4   ;Move R4 into the Accumulator
 MOV B,R7   ;Move R7 into B
 MUL AB     ;Multiply the two values
 ADD A,R2   ;Add the low-byte into the value already in R2
 MOV R2,A   ;Move the resulting value back into R2
 MOV A,B    ;Move the high-byte into the accumulator
 ADDC A,R1  ;Add the current value of R1 (plus any carry)
 MOV R1,A   ;Move the resulting answer into R1.
 MOV A,#00h ;Load the accumulator with zero
 ADDC A,R0  ;Add the current value of R0 (plus any carry)
 MOV R0,A   ;Move the resulting answer to R1.

Step 4. Multiply R4 by R6, adding the 16-bit result to R0 and R1.

 MOV A,R4  ;Move R4 back into the Accumulator
 MOV B,R6  ;Move R6 into B
 MUL AB    ;Multiply the two values
 ADD A,R1  ;Add the low-byte into the value already in R1
 MOV R1,A  ;Move the resulting value back into R1
 MOV A,B   ;Move the high-byte into the accumulator
 ADDC A,R0 ;Add it to the value already in R0 (plus any carry)
 MOV R0,A  ;Move the resulting answer back to R0

Combining the code from the two steps above, we come up with the following subroutine:

MUL16_16: 
 ;Multiply R5 by R7
 MOV A,R5 ;Move the R5 into the Accumulator
 MOV B,R7 ;Move R7 into B
 MUL AB   ;Multiply the two values
 MOV R2,B ;Move B (the high-byte) into R2
 MOV R3,A ;Move A (the low-byte) into R3

 ;Multiply R5 by R6
 MOV A,R5    ;Move R5 back into the Accumulator
 MOV B,R6    ;Move R6 into B
 MUL AB      ;Multiply the two values
 ADD A,R2    ;Add the low-byte into the value already in R2
 MOV R2,A    ;Move the resulting value back into R2
 MOV A,B     ;Move the high-byte into the accumulator
 ADDC A,#00h ;Add zero (plus the carry, if any)
 MOV R1,A    ;Move the resulting answer into R1
 MOV A,#00h  ;Load the accumulator with  zero
 ADDC A,#00h ;Add zero (plus the carry, if any)
 MOV R0,A    ;Move the resulting answer to R0.

 ;Multiply R4 by R7
 MOV A,R4   ;Move R4 into the Accumulator
 MOV B,R7   ;Move R7 into B
 MUL AB     ;Multiply the two values
 ADD A,R2   ;Add the low-byte into the value already in R2
 MOV R2,A   ;Move the resulting value back into R2
 MOV A,B    ;Move the high-byte into the accumulator
 ADDC A,R1  ;Add the current value of R1 (plus any carry)
 MOV R1,A   ;Move the resulting answer into R1.
 MOV A,#00h ;Load the accumulator with zero
 ADDC A,R0  ;Add the current value of R0 (plus any carry)
 MOV R0,A   ;Move the resulting answer to R1.

 ;Multiply R4 by R6
 MOV A,R4  ;Move R4 back into the Accumulator
 MOV B,R6  ;Move R6 into B
 MUL AB    ;Multiply the two values
 ADD A,R1  ;Add the low-byte into the value already in R1
 MOV R1,A  ;Move the resulting value back into R1
 MOV A,B   ;Move the high-byte into the accumulator
 ADDC A,R0 ;Add it to the value already in R0 (plus any carry)
 MOV R0,A  ;Move the resulting answer back to R0

 ;Return - answer is now in R0, R1, R2, and R3
 RET

And to call our routine to multiply the two values we used in the example above, we'd use the code:

 ;Load the first value into R6 and R7
 MOV R6,#62h
 MOV R7,#30h
 
 ;Load the first value into R4 and R5
 MOV R4,#43h
 MOV R5,#2Eh

 ;Call the 16-bit subtraction routine
 LCALL MUL16_16 


Previous: 16-Bit Subtraction Tutorial Contents Next: 16-Bit Division