Reputation: 168
On a IA-32 architecture how do I sum/subtract two 32-bit signed values and store the result in a 64-bit (EDX:EAX) while mantaining the sign?
For this 32 bit values :
A = 97
B = 232
C = 2147483600
D = 200
How do I do C + A - D + B and return a 64 bit value in Assembly?
Note: the result from C + A overflows the 32-bit registry.
I tried to use the adc function to add the carry to the edx after adding C to A but, since its signed, it does not do what i pretend.
What i tried for C+A, but it does not keep the sign:
#Prologue
pushl %ebp
movl %esp, %ebp
#Body
movl $0, %edx
movl $0, %ecx
movl $0, %eax
movb 8(%ebp), %al #
movsx %al, %eax #move with sign extention to 32 bit eax
addl 16(%ebp), %eax #adding C + A
adcl $0, %edx
I also have the same problem if C was -97 and A was -2147483600 (for negative values).
Upvotes: 0
Views: 487
Reputation: 14409
The best way is to expand the 32-bit signed values to 64-bit signed values before the respective calculation with CDQ
:
.section .data
fmt: .string "Result: %lli\n"
.section .text
.globl main
main:
pushl $97 # A
pushl $232 # B
pushl $2147483600 # C
pushl $200 # D
call do_it
add $8, %esp
push %edx
push %eax
push $fmt
call printf
add $8, %esp
pushl $0
call exit
do_it:
pushl %ebp # Prologue
movl %esp, %ebp
mov 12(%ebp), %eax # C
cdq
mov %edx, %edi # X = C
mov %eax, %esi
mov 20(%ebp), %eax # A
cdq
add %eax, %esi
adc %edx, %edi # X += A
mov 8(%ebp), %eax # D
cdq
sub %eax, %esi # X -= D
sbb %edx, %edi
mov 16(%ebp), %eax # B
cdq
add %eax, %esi
adc %edx, %edi # X += B
mov %edi, %edx # RETURN = X
mov %esi, %eax
leave # Epilogue
ret
Upvotes: 1