在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(对于负值),我也会遇到相同的问题。
答案 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