I want to add two numbers that have 12 bytes and to store the result in a 16 bytes var. How can i do this?
section .data
big_num1 dd 0x11111111, 0x22222222, 0x33333333
big_num2 dd 0xffffffff, 0x22222222, 0x33333333
section .bss
result_4word resd 4
I think i can add the first 4 bytes number from number 1 with the other first 4 bytes from number 2 and so on.. but i don't know how to concatenate results in in my result variable. How should i do the carry,if it's needed? Is this solution the right one?
xor eax, eax
xor ebx, ebx
mov ecx, 3
loop1:
mov eax, dword[big_num1+4*(ecx-1)]
mov ebx, dword[big_num2+4*(ecx-1)]
mov [result_4word+4*(ecx-1)], eax
adc [result_4word+4*(ecx-1)], ebx
loop loop1
What numbers are defined here?
Because x86 is a little-endian architecture, the lowest part of a number is stored in memory at the lowest addresses. For big_num1 the first defined dword (value is 0x11111111) is at the lowest address and thus is the lowest part of the number. In the normal number representation this is what goes at the right-handside.
Adding big numbers
You add corresponding digits going from right to left, just like everybody has learned at school.
In the hexadecimal representation of these numbers there are 24 digits to consider. However since the architecture is 32-bit, we can nicely make 3 groups of 8 digits.
For the 1st group we simply use
ADD:For the 2nd group we use
ADCto pick up a possible carry from the previous addition:For the 3rd group we use
ADCto pick up a possible carry from the previous addition:Turning this into a loop
Key here is that we can also use
ADCfor the 1st group if we expressly clear the carry flag beforehand:Now we can write a loop with 3 iterations but we have to be careful about not changing the carry flag inadvertently. That's why I use
LEAinstead ofADDin order to advance the offset.DECis also an instruction that does not destroy the carry flag. I've preferred the comboDEC ECXJNZ ...because it's better thanLOOP ...:If after these 3 additions there's still a set carry, you'll have to write a 1 in the 4th dword of result_4dword, else you'll have to write a 0 here. Because result_4dword is in the .bss section, you should not count on any preset value like zero!
Please note that I've changed result_4word into result_4dword. Makes more sense...