The MASM Forum

General => The Campus => Topic started by: maelirou on March 31, 2016, 09:13:27 AM

Title: Adding two 64 bit long numbers in Masm 32
Post by: maelirou on March 31, 2016, 09:13:27 AM
Hi guys.
I don`t know how to calculate two 64 bit long numbers,
"3A2C098FDE6273ED" with "26D371B41CA8B4F6" and that result "60FF7B43FB0B28E3" to show in MessageBox?
I`m using MASM for x86, btw.
Do i have to use the FPU registers and how? I would appreciate really a lot some code example!
Sorry for any mistakes. English is not my native language.


I only know how to calculate 32 bit long number with the FPU.

MyF_ proc
LOCAL P1_:QWORD
LOCAL P2_:QWORD
LOCAL Result_:QWORD
 
    mov dword ptr [_P1],576ED371h
    mov dword ptr [_P2],1AC54331h
    FLD _FP1   
    FLD _FP2   
    FADD ST(0), ST(1)
    fstp _Result   
    mov eax,dword ptr[_Result]                          ; eax = 723416A2

MyF_ endp

:t
Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: raymond on March 31, 2016, 10:11:06 AM
You don't necessarily need to use the fpu for such an operation unless you have some other needs. Simply imagine you have to add 58+25 with paper and pencil.
  5 8
+2 5
____
  8 3

You would first add the lower part, keep the lower result, and carry over (when needed) the one for the addition of the higher part.

You use 32-bit registers for the lower and higher parts of 64-bit numbers.


.data
  num1    qword    3A2C098FDE6273EDh
  num2    qword    26D371B41CA8B4F6h
  result  qword    ?

.code
  mov   eax,dword ptr num1      ;lower 32-bit part of num1
  mov   edx,dword ptr num1[4]   ;higher 32-bit part of num1
  add   eax,dword ptr num2      ;add lower 32-bit part of num2 with lower 32-bit part of num1
  adc   edx,dword ptr num2[4]   ;add with carry the higher 32-bit part of num2 with higher 32-bit part of num1
  mov   dword ptr result,eax    ;mov the lower 32-bit part of the sum to the lower 32-bit part of result
  mov   dword ptr result[4],edx ;mov the higher 32-bit part of the sum to the higher 32-bit part of result


You can either use the result for further computations or convert it to ascii for display; you can use whatever algo you want for conversion but, if needed, you would find functions in the fpulib (umqtoa or smqtoa) to convert qwords to a decimal integers.
Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: maelirou on March 31, 2016, 10:32:56 AM
Omg, I'm embarrassed now.
Thank you so much for your answer, code example and fast reply!
It`s perfect and simple for asm.   :t
Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: jj2007 on March 31, 2016, 01:11:49 PM
Hi maelirou, welcome to the forum :icon14:

Quote from: raymond on March 31, 2016, 10:11:06 AM
You don't necessarily need to use the fpu for such an operation

Raymond is our FPU guru - don't take his advice too seriously:

  fild num1
  fild num2
  fadd
  fistp result


Much simpler, right?

Quoteyou can use whatever algo you want for conversion

If you are coming from a C/C++ background, you might be tempted to use fprintf(). Here is an example:
include \masm32\include\masm32rt.inc

.data
num1    qword    3A2C098FDE6273EDh
num2    qword    26D371B41CA8B4F6h
result  qword    ?

.code
start:
  fild num1
  fild num2
  fadd
  fistp result
  printf("The calculated sum is \t%I64X\n", result)
  printf("The expected sum is\t%s\n", "60ff7b43fb0b28e3")
  inkey "--- that was uncool, right? ---"
  exit
end start


Output:
The calculated sum is   60FF7B43FB0B2800
The expected sum is     60ff7b43fb0b28e3
--- that was uncool, right? ---


Hex$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1198) does it properly but requires an extra library:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
.data
num1    qword    3A2C098FDE6273EDh
num2    qword    26D371B41CA8B4F6h
result  qword    ?
  Init
  fild num1
  fild num2
  fadd
  fistp result
  PrintLine "The calculated sum is", Tb$, Hex$(result)
  printf("The expected sum is\t%s\n", "60FF7B43 FB0B28E3")
  inkey "--- that was cool, right? ---"
EndOfCode


Output:
The calculated sum is   60FF7B43 FB0B28E3
The expected sum is     60FF7B43 FB0B28E3


But there is a shorter method to convince printf() to display result correctly: finit as first instruction after the start label ;-)
Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: MichaelW on April 03, 2016, 04:28:04 PM
I verified the correct result with the Windows calculator, and included an integer calculation.


include \masm32\include\masm32rt.inc

.data
num1    qword    3A2C098FDE6273EDh
num2    qword    26D371B41CA8B4F6h
result  qword    ?

.code
start:

    fild num1
    fild num2
    fadd
    fistp result
    printf("The calculated sum is \t%I64X\n\n", result)

    ; Init FPU for full 64-bit precision, instead of the
    ; 56-bit precision that Windows sets up.
   
    finit
   
    fild num1
    fild num2
    fadd
    fistp result
    printf("The calculated sum is \t%I64X\n\n", result)
   
    mov     eax, DWORD PTR num1[0]
    mov     ebx, DWORD PTR num2[0]
    mov     ecx, DWORD PTR num1[4]
    mov     edx, DWORD PTR num2[4]
     
    ; Add low-order DWORDs.       
   
    add     eax, ebx
   
    ; Add high-order DWORDs with any carry from low-order addition.
   
    adc     ecx, edx

    ; Store results.
   
    mov     DWORD PTR result[0], eax
    mov     DWORD PTR result[4], ecx   
   
    printf("The calculated sum is \t%I64X\n\n", result)
    printf("The expected sum is\t%s\n\n", "60ff7b43fb0b28e3")
    inkey
    exit
end start


The calculated sum is   60FF7B43FB0B2800

The calculated sum is   60FF7B43FB0B28E3

The calculated sum is   60FF7B43FB0B28E3

The expected sum is     60ff7b43fb0b28e3
Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: jj2007 on April 03, 2016, 05:01:42 PM
Quote from: MichaelW on April 03, 2016, 04:28:04 PM
    ; Init FPU for full 64-bit precision, instead of the
    ; 56-bit precision that Windows sets up.
    finit

That was indeed the point. Interesting that Raymond's example prints fine when using
printf("The result is %llx", result)

It seems printf() doesn't use the FPU at all, precision is still 53 bits when returning.
Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: Mikl__ on April 25, 2016, 07:11:47 PM
lea esi,x
lea ebx,y
lea edi,result
mov ecx,8
clc
@@: lodsb
adc al,[ebx]
stosb
inc ebx
loop @b
adc byte ptr [edi],0
Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: qWord on April 26, 2016, 01:25:32 AM
Quote from: Mikl__ on April 25, 2016, 07:11:47 PM
lea esi,x
lea ebx,y
lea edi,result
mov ecx,8
clc
@@: lodsb
adc al,[ebx]
stosb
inc ebx
loop @b
adc byte ptr [edi],0

Inconvenient and buggy solution (Byte result[8] is modified).
See Raymond's post for compare:
Quote from: raymond on March 31, 2016, 10:11:06 AM

  mov   eax,dword ptr num1      ;lower 32-bit part of num1
  mov   edx,dword ptr num1[4]   ;higher 32-bit part of num1
  add   eax,dword ptr num2      ;add lower 32-bit part of num2 with lower 32-bit part of num1
  adc   edx,dword ptr num2[4]   ;add with carry the higher 32-bit part of num2 with higher 32-bit part of num1
  mov   dword ptr result,eax    ;mov the lower 32-bit part of the sum to the lower 32-bit part of result
  mov   dword ptr result[4],edx ;mov the higher 32-bit part of the sum to the higher 32-bit part of result

Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: Mikl__ on April 26, 2016, 11:36:36 AM
Quote from: qWordInconvenient and buggy solution (Byte result[8] is modified)
Really? And it seemed to me is suitable both for 8-and for 64-bit microprocessors and doesn't depend on length of composed.
And if you add some 64-bit values (for example 0FFFFFFFFFFFFFFFFh and 1) the result can be 65-bit
Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: raymond on April 26, 2016, 02:09:11 PM
QuoteReally?

You are correct that the addition of two 64-bit numbers could overflow and such a possibility must be incorporated in the code.

I think qWord's comment pertained to the fact that your "result" label was not defined in the code you provided. In many of the previous posts, it was defined as a qword (which does not have a 65th bit). Moreover, depending where your '8 bytes' would be reserved for storing the 64-bit result (such as on the stack), the next byte may not have been a '0' and adding 0 with carry to that next byte could be buggy to use qWord's description.
Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: mabdelouahab on April 26, 2016, 03:21:16 PM
Quoteinclude \masm32\include\masm32rt.inc
.686
.XMM
.data
    q1  dq  03A2C098FDE6273EDh
    q2  dq  026D371B41CA8B4F6h
    qr  dq  0
.code
start:

    movq    mm0, q1
    movq    mm1, q2
    paddq   mm0, mm1
    movq    qr, mm0
    printf("   %I64Xh\n",q1)
    printf("+   %I64Xh\n",q2)
    printf("=   %I64Xh\n\n",qr)

    inkey
    exit
   
end start
Quote3A2C098FDE6273EDh
+       26D371B41CA8B4F6h
=       60FF7B43FB0B28E3h

Press any key to continue ...
Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: Mikl__ on April 26, 2016, 05:18:03 PM
Hi, raymond!
Quote from: raymondI think qWord's comment pertained to the fact that your "result" label was not defined in the code you provided
I thought that it is obvious without explanations
.data
x dq 0F897654FDE6273EDh
y dq 26D371B41CA8B4F6h
result db 9 dup (0)
Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: jj2007 on April 26, 2016, 06:02:35 PM
Quote from: Mikl__ on April 26, 2016, 05:18:03 PMresult db 9 dup (0)

When the result needs 9 bytes, the debate becomes a bit "academic". In practice, you should be aware of your limits, and if your program really needs 9 bytes, you'd better go for a REAL8. Or you go for Dave's Ling Long Kai Fang (http://masm32.com/board/index.php?topic=222.msg19324#msg19324) ;)
Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: Mikl__ on April 26, 2016, 06:27:46 PM
QuoteWhen the result needs 9 bytes, the debate becomes a bit "academic". In practice, you should be aware of your limits, and if your program really needs 9 bytes, you'd better go for a REAL8
Hi, jj2007!
I don't understand what about we argue. If you add two N-byte unsigned integer numbers, then you reserve N+1-bytes for result. If you multiply  two N-byte unsigned integer numbers, then you reserve 2*N bytes for result. Isn't it?
Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: jj2007 on April 26, 2016, 07:16:51 PM
Sure, your logic is correct. But in real life, how would you handle (e.g. print) a "Q+1-WORD" variable, and why would you use one? A REAL8 has no such problems, and is only 0.0000000000000000001% less precise than the QWORD. That is why I consider the problem "academic". We argue about it because we like arguing...
Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: Mikl__ on April 26, 2016, 07:26:02 PM
QuoteWe argue about it because we like arguing...
Benissimo! (http://www.cyberforum.ru/images/smilies/popcorn.gif)
Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: jj2007 on April 26, 2016, 07:33:59 PM
I love that icon :t Beer & chips for the lurkers, yeah :greensml:
Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: qWord on April 26, 2016, 11:02:11 PM
Mikl__,

your solution is inconvenient because it needs 4 times more memory accesses than the classical approach, beside that the later one is branch-free. Also the results 8th Byte must be zeroed out before going into your code (static initialization does not count in general context).

Quote from: Mikl__ on April 26, 2016, 11:36:36 AMAnd it seemed to me is suitable both for 8-and for 64-bit microprocessors and doesn't depend on length of composed.
If you are interested in portability than you are wrong in using assembler. Your code might (depending on the memory addresses) run in x64, but I don't know any 8 Bit MCU that accept above code. Of course, the algorithm will work with any ISA that allows to add with carry.
Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: raymond on April 27, 2016, 01:16:46 AM
QuoteI thought that it is obvious without explanations

In my opinion, this does not hold in assembly. I strongly believe in my signature "Whenever you assume ..."
Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: Mikl__ on April 27, 2016, 10:40:07 AM
Hi, qWord!
Quoteyour solution is inconvenient because it needs 4 times more memory accesses than the classical approach, beside that the later one is branch-free. Also the results 8th Byte must be zeroed out before going into your code (static initialization does not count in general context).
maelirou didn't set a task of optimization of the program for speed or the volume occupied in memory. Your answers (at everything to you respect) are maintenance of dispute for the sake of the dispute
QuoteWe argue about it because we like arguing...
Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: TouEnMasm on April 28, 2016, 10:23:41 PM

I will argue with c

;asm call
invoke calcul,OneReal,TwoReal,addr result
// Adding two REAL
int calcul(double truc,double chose,double * presult)
{
*presult = truc + chose;
return 0;
};
;32 bits
_calcul PROC ; COMDAT
; File h:\pratique\math_asm_c\feuille_calcul_c.c
; Line 21
push ebp
mov ebp, esp
sub esp, 64 ; 00000040H
push ebx
push esi
push edi
; Line 22
movsd xmm0, QWORD PTR _truc$[ebp]
addsd xmm0, QWORD PTR _chose$[ebp]
mov eax, DWORD PTR _presult$[ebp]
movsd QWORD PTR [eax], xmm0
; Line 23
xor eax, eax
; Line 24
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret 0
_calcul ENDP

;64 bits
calcul PROC ; COMDAT
mov QWORD PTR [rsp+24], r8
movsd QWORD PTR [rsp+16], xmm1
movsd QWORD PTR [rsp+8], xmm0
push rbp
sub rsp, 64 ; 00000040H
mov rbp, rsp
movsd xmm0, QWORD PTR truc$[rbp]
addsd xmm0, QWORD PTR chose$[rbp]
mov rax, QWORD PTR presult$[rbp]
movsd QWORD PTR [rax], xmm0
xor eax, eax
lea rsp, QWORD PTR [rbp+64]
pop rbp
ret 0
calcul ENDP

Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: raymond on April 29, 2016, 02:10:56 AM
QuoteI will argue with c

To continue the argument, which part of your code checks for overflow of 64-bit integers???
Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: TouEnMasm on April 29, 2016, 03:01:25 AM
The cool thing with C is that there is just to ask and it is found
http://stackoverflow.com/questions/199333/how-to-detect-integer-overflow-in-c-c
http://stackoverflow.com/questions/15655070/how-to-detect-double-precision-floating-point-overflow-and-underflow
Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: raymond on April 29, 2016, 03:15:18 AM
Quotewhich part of your code checks for overflow of 64-bit integers

I was asking about the code you actually posted as examples, and to be more specific when you used floats to perform the addition.
Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: TouEnMasm on April 29, 2016, 03:32:48 AM
none
but you have this solution for double
http://forums.codeguru.com/showthread.php?525081-double-overflow-detection
Title: Re: Adding two 64 bit long numbers in Masm 32
Post by: qWord on April 29, 2016, 05:13:38 AM
Quote from: ToutEnMasm on April 29, 2016, 03:32:48 AM
but you have this solution for double
... in C#