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



在 IA-32 架构上,如何在保留符号的同时对两个32 位有符号值求和/减去并将结果存储在64 位(EDX:EAX( 中?

对于此 32 位值:

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

如何执行 C + A - D + B 并在汇编中返回 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(对于负值(,我也有同样的问题。

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

.section .data
fmt: .string "Result: %llin"
.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

最新更新