Diogo Soares
Diogo Soares

Reputation: 168

Assembly IA-32: Adding/subtracting 32-bit signed values and returning a signed 64-bit

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

Answers (1)

rkhb
rkhb

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

Related Questions