assembly - 如何在 IA32 上将带符号的整数求和为更宽的和。 32 位有符号整数的 64 位和?

标签 assembly x86 att sign-extension

我正在尝试对 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/

相关文章:

assembly - 在编译时从 MASM/MASM64 检测架构

c - 深入 assembly

image - 在asm中翻转图像中的第一个像素

assembly - 如何让 gdb 反汇编整个函数?

android - 发送和接收自定义数据并为其使用付费的应用

linux - 如何使用静态数组的结束指针作为循环条件来比较 x86 中的地址?

assembly - 在 assembly 中进入和离开?

assembly - ldr 中相同的源和目标寄存器

visual-c++ - 如何用C/C++通过CPUID命令获取物理和虚拟地址位

linux - 如何将字符串数组作为参数传递给函数?