1

I need to write a macro for adding 2 64bit on a 32bit machine.
One way I thought about is as follows:

%macro add_double 2
mov edx, %1
add %2,edx
mov edx,%1
shl edx,31
mov eax,%2
shl eax,31
add eax,edx
add %2,eax
%endmacro

will this even work? also I was wondering... there is a simple way of doing it using [] but is it possible doing [%1] for example in a macro? I am new to assembly so I don't know.

Tai
  • 59
  • 5
  • 2
    Where are these two 64-bit values located? In two 32-bit register pairs? If so, wouldn't your macro need 4 arguments? Anyway, your current implementation doesn't look correct to me. I didn't try running it, but it looks like if you gave 1 and 0 as arguments you'd get 0x80000001 as the result. – Michael Jun 29 '15 at 13:14
  • 2
    `adc` is specifically invented for this. – Jester Jun 29 '15 at 13:31

1 Answers1

2

To add numbers in chunks of 32 bit you have to use the fact that add set the CF. So the low 32 bits are added as normal, the high ones are added with adc which include the carry flag in the addition.

These macros should do

%macro add_double 4
mov eax, %1
mov edx, %2
add eax, %3
adc edx, %4
%endmacro

%macro add_doublev 2
mov eax, DWORD [%1]
mov edx, DWORD [%1+04h]
add eax, DWORD [%2]
adc edx, DWORD [%2+04h]
%endmacro

The add_double takes 4 32 bits numbers, the first are the low 32 bits of the first number, the second the 32 high bits. The other two number are the same but for the second number. To add 0xff00000000 to 0x8800000000 use it as add_double 0, 0ffh, 0, 88h.
The add_doublev takes 2 addresses from which to fetch the two 64 bits numbers (in little endian). Use it as

num1 dd 0, 0ffh
num2 dd 0, 088h

add_doublev num1, num2

Both macros compute the result in EDX:EAX, meaning that EDX holds the upper 32 bits and EAX the lower 32 bits.