程序集IA-32:添加/减去32位带符号的值并返回带符号的64位

时间:2018-10-19 18:51:19

标签: assembly x86 att

在IA-32架构上,我如何求和/减去两个 32位带符号值并将结果存储在 64位(EDX:EAX)中,维护标志?

对于这32位值:

A = 97
B = 232
C = 2147483600
D = 200

如何执行C + A-D + B并在 Assembly 中返回64位值?

注意:C + A的结果会使32位注册表溢出。

在将C添加到A之后,我尝试使用 adc 函数将进位添加到edx中,但是,由于已签名,所以它没有执行我的装扮。

我为C + A所做的尝试,但并没有保持这种迹象:

#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

如果C为-97,A为-2147483600(对于负值),我也会遇到相同的问题。

1 个答案:

答案 0 :(得分:1)

最好的方法是在使用CDQ进行相应的计算之前,将32位有符号值扩展为64位有符号值:

.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