我正在尝试对 Assembly 32 上带符号的整数列表求和,但我只能对不带符号的整数求和。你知道一些方法吗?
我的程序尝试对整数求和并存储在 resultado
中,其大小为 64 位,因此为了能够做到这一点,我使用了两个 32 位寄存器(EAX 和 EDX),然后我检查当总和产生进位时。
之后,我在 resultado 上加入了 EAX 和 EDX。
# sum.s Sumar los elementos de una lista.
# llamando a función, pasando argumentos mediante registros
# retorna: código retorno 0, comprobar suma en %eax mediante gdb/ddd.
# as --32 -g sum.s -o sum.o
# ld -m elf_i386 sum.o -o sum
# DATA SECTION
.section .data
lista:
.int 4294967295, 4294967295, 4294967295, 4294967295
longlista:
.int (.-lista)/4
resultado:
.quad -1
.section .text
_start: .global _start
mov $lista, %ebx
mov longlista, %ecx
call suma
mov %eax, resultado
mov %edx, resultado+4
mov $1, %eax
mov $0, %ebx
int $0x80
suma:
push %esi
mov $0, %eax
mov $0, %edx
mov $0, %esi
bucle:
add (%ebx,%esi,4), %eax
jc .L1
bucle1:
inc %esi
cmp %esi,%ecx
jne bucle
pop %esi
ret
.L1:
inc %edx
jmp bucle1
这给出了一个 64 位总和,将输入视为无符号 32 位,这不是我想要的。
最佳答案
下一个使用 64 位加法的代码将为正数和负数提供正确的总和,而不会由于仅使用 32 位寄存器而产生任何回绕。
签名结果可能超出范围[-2GB,+2GB-1]。
suma:
push %esi
push %edi
xor %esi, %esi ;Clear %edi:%esi
xor %edi, %edi
sub $1, %ecx ;Start at last element in array
jl emptyArray
bucle:
mov (%ebx,%ecx,4), %eax ;From signed 32-bit to signed 64-bit
cdq
add %eax, %esi ;Add signed 64-bit numbers
adc %edx, %edi
dec %ecx
jge bucle
emptyArray:
mov %esi, %eax ;Move result from %edi:%esi to %edx:%eax
mov %edi, %edx
pop %edi
pop %esi
ret
添加的顺序并不重要,因此代码从最后一个元素开始,然后逐渐转向第一个元素。
关于assembly - 如何在 IA32 上将带符号的整数求和为更宽的和。 32 位有符号整数的 64 位和?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47124737/