Pretend you're multiplying two 2-digit numbers by hand.
You can multiply two 2-register-wide numbers in Exactly the same way.
Main Topics
Browse All TopicsI am trying to multiply two 64 bit unsigned numbers using only 32 bit words. I understand how to multiply two 32 bit unsigned numbers but I cant figure out how to get the 64 bit number into two 32 bit words. Can someone give me an idea. Here is my 32 bit multiplication program. Any help would greatly be appreciated as I am new to the spim assembly language.
## $t1 mask
## $t2 multiplier (and right_hand_sum).
## $t3 left_hand_sum.
## $t4 multiplicand.
## $t5 - clear.
## $t6 - rightmost bit of left_hand_sum.
## $t7 - rightmost bit of right_hand_sum.
## $t8 - counter
## $v0 syscall parameter / return values.
## $a0 syscall parameters.
## $a1 syscall parameters.
.text
.globl __start
__start:
## read the two integers
li $v0, 5 # load multiplicand.
syscall
move $t4, $v0
li $v0, 5 # load multiplier.
syscall
move $t2, $v0
lw $t1, mask
lw $t5, clear
li $t8, 32
continue:
beqz $t8, end
and $t7, $t1, $t2
beqz $t7, shift
add $t3, $t3, $t4
shift: and $t6, $t3, $t1 # store rightmost bit og l_sum in $t6
and $t2, $t2, $t5 # clear rightmost bit of r_sum
or $t2, $t2, $t6 # move stored right bit of l_sum to rightmost position of r_sum
ror $t2, $t2, 1 # rotate r_sum
srl $t3, $t3, 1 # shift l_sum right
# Use sra for twos complement numbers
addiu $t8, $t8, -1
b continue
end: sw $t2, r_sum
sw $t3, l_sum
li $v0, 10
syscall
.data
r_sum: .word 0
l_sum: .word 0
mask: .word 0x00000001
clear: .word 0xFFFFFFFE
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
Let's assume that you have two 64-bit numbers: Z1 and Z2. Their multiplication with give you 128-bit result.
You can multiply 32-bit on 32-bit.
So declare Z1 = Y1 0 + X1 (where X1 is lower 32-bit and Y1 is higher 32-bit)
Z2 = Y2 0 + X2
Then Z1 * Z2 = (Y1 0 + X1 ) * (Y2 0 + X2)
And you need to find only 32-bit multiplications BUT for example Y1 0 * Y2 0 = Y1*Y2 0 0 (where Y1 * Y2 is upper 64-bit value of 128-bit result).
Hope it will help you...
x86, very fast and efficient, any number size (>= 64 bits):
BNMul proc lpBNResult:DWORD, lpBN1:DWORD, lpBN2:DWORD
;--T:BOOL
;--G:Multiplies two Big Numbers and stores the result to lpBNResult. Returns -1 on overflow.
;--H:
local lpBNLocal:DWORD
local lpBNRes:DWORD
local dwValue:DWORD
mov eax,0
pushad
PUSH_STACK_BN lpBNLocal
PUSH_STACK_BN lpBNRes
;clears lpBNResult
mov eax,0
mov ecx,dwArraySize
;unrolled BNSet0 >>>>>
mov edi,lpBNResult
push ecx
rep stosd
pop ecx
;<<<<<<<<<<<<<<<<<<<<<
;tests if lpBN1 or lpBN2 are 0, if so, exit
;unrolled BNIs0 >
mov edi,lpBN1
push ecx
repz scasd
pop ecx
.if ZERO?
jmp @F
.endif
;<<<<<<<<<<<<<<<<
;unrolled BNIs0 >
mov edi,lpBN2
push ecx
repz scasd
pop ecx
.if ZERO?
jmp @F
.endif
;<<<<<<<<<<<<<<<<
;copies lpBN1 to lpBNLocal, which is then shifted to the left
;unrolled BNCopy >>>>
mov esi,lpBN1
mov edi,lpBNLocal
push ecx
rep movsd
pop ebx ;holds the iteration count
;<<<<<<<<<<<<<<<<<<<<
;computes the number of bits of the multiplier, which are the
;iterations - 1
dec ebx
mov ecx,lpBN2 ;holds the DWORD offset
.repeat
;tests if the DWORD is set
.if dword ptr [ecx]
;if it is, multiply lpBNLocal by dword ptr [ecx] and
;add lpBNRes to lpBNResult
mov eax,[ecx]
mov dwValue,eax
;unrolled BNMulByDWORD >>
pushad
mov ebx,0 ;Carry
mov ecx,dwArraySize
mov edi,lpBNRes
;unrolled BNCopy
mov esi,lpBNLocal
push ecx
push edi
rep movsd
pop edi
pop ecx
;<<<<<<<<<<<<<<<
dec ecx
.repeat
mov eax,[edi]
mul dwValue
add eax,ebx
mov ebx,0
mov [edi],eax
lea edi,[edi+4]
adc ebx,edx
dec ecx
.until SIGN?
;check for overflow
; .if dword ptr [edi-4] & 80000000h
; retv -1
; .endif
.if ebx
retv -1
.endif
popad
;<<<<<<<<<<<<<<<<<<<<<<<<
;unrolled BNAddEx >>>>>
pushad
mov ecx,dwArraySize
mov esi,lpBNRes
mov edi,lpBNResult
sub ecx,1 ;dec ecx|and eax,eax
.repeat
mov eax,[esi]
lea esi,[esi+4]
adc [edi],eax
lea edi,[edi+4]
dec ecx
.until SIGN?
popad
;<<<<<<<<<<<<<<<<<<<<<<
.if CARRY?
retv -1
.endif
.endif
;shift lpBNLocal (ex lpBN1) 32 bits to the left, ignore CARRY
;unrolled BNShl32Ex >>>>>
push ecx
push esi
push edi
mov ecx,dwArraySize
mov esi,lpBNLocal
dec ecx
lea edi,[esi+ecx*4]
lea esi,[esi+ecx*4-4]
std
rep movsd
cld
mov dword ptr [edi],0
pop edi
pop esi
pop ecx
;<<<<<<<<<<<<<<<<<<<<<<<
lea ecx,[ecx+4] ;DWORD offset
dec ebx ;iterations
.until SIGN?
@@:
POP_STACK_BN
POP_STACK_BN
popad
ret
BNMul endp
Business Accounts
Answer for Membership
by: mtmikePosted on 2003-10-16 at 15:28:37ID: 9566002
You probably mean mips assembly using the spim simulator. Since this looks like homework, I won't give you any code, just some hints.
Mips has the mul instruction to multiply two 32-bit registers, no need to write your own.
There's the widening multiply instruction multu that multiplies two unsigned 32 bit registers into a 64-bit result. The two special hi and lo registers are used to store this result.
A 64-bit multiply can be performed using one such widening multiply, two normal 32-bit multiplies and two 32-bit adds.