0

So here is the numbers

a = 234234  
b = 2394729  
c = 12323  
a*b*c = 6912302836717278  

but i am getting this result: 3945371358.

I think i have to use LONG because it is over the int's limit but i don't know how ,because there is no long in assembly x86 , what i have to change ? Thanks in advance

%include "io.inc"
section .bss
a resd 1
b resd 1
c resd 1
section .text
global CMAIN
CMAIN:
    mov ebp, esp; for correct debugging
   xor eax,eax
    GET_UDEC 4,a
    GET_UDEC 4,b
    GET_UDEC 4,c
    mov eax,dword[a] 
    mov ebx,dword[b] 
    imul ebx
    mov ecx,dword[c]
    imul ecx
    PRINT_UDEC 4, eax
    xor eax, eax
    ret
FAR CRY 3
  • 37
  • 5
  • 2
    "i am using imul because they have to be unsigned" You've got that backwards, MUL is an unsigned multiply, IMUL is the signed multiply. – Thomas Jager May 12 '20 at 17:43
  • 2
    You're only printing the low dword of the result (from EAX). Also, the 2nd multiply is only reading the 32 bit result of the first. Widening multiply (one operand `mul` or `imul`) does `EDX:EAX = EAX * src`. If the first multiply doesn't overflow, then you can just use `mul` twice. See the manual: https://www.felixcloutier.com/x86/mul. But if `c` is small so `a*b` overflows 32 bits while `a*b*c` fits in 64 bits, that's a problem. – Peter Cordes May 12 '20 at 21:20
  • You could maybe sort and do keep the largest value for last, or just do full 64x64 => 64 multiply using multiple `mul` and `add` instructions. Look at compiler output. – Peter Cordes May 12 '20 at 21:21

1 Answers1

3

It is true that multiplying the two smallest values in your example results in a 32-bit number, but only just. You can't assume that this will always be the case. So you have two choices:

  • implement 64x64-bit multiplication by hand, using schoolbook multiplication;
  • build a 64-bit application. Then you can use 64-bit rax etc. instead of 32-bit eax.
TonyK
  • 16,761
  • 4
  • 37
  • 72