汇编 32bits 两个向量的元素之和

Assembly 32bits sum of elements of two vectors

我对两个大小相同的双精度型向量的元素求和有疑问。代码总是 returns 0.

#include <iostream>
using namespace std;
int main()
{
    int n = 5;
    double* tab = new double[n];
    double* tab3 = new double[n];
    for (size_t i = 0; i < n; i++)
    {
        tab[i] = 1;
        tab3[i] = 1;
    }
    double sum;
    __asm {
        mov eax, n; //vector size
        mov edi, tab; //first vector
        mov esi, tab3; //second vector
        fldz;
    l:
        fadd[edi + 8 * eax - 8];
        fadd[esi + 8 * eax - 8];
        dec eax;
        jnz l;
        fstp sum;
    }
    cout << sum;
}

遗憾的是我不在 windows,所以我不得不修改代码以使用 g++ 而不是 msvc,但我也使用了英特尔语法汇编。在调试过程中发现 fadd 指令没有效果。我通过在 [edi + 8 * eax - 8][esi + 8 * eax - 8] 之前添加 qword ptr 来告诉汇编程序使用指向 8 字节值的指针来修复它(因为您使用的是 double 而不是 float):

fadd qword ptr [edi + 8 * eax - 8];
fadd qword ptr [esi + 8 * eax - 8];

所以你正在为这段 C 代码寻找 asm,对吗? https://godbolt.org/z/vbdfEb94s

#include <cstddef>

double add(double *a, double *b, std::size_t len) {
    double sum = 0;
    while (len-- > 0) {
        sum += *a++;
        sum += *b++;
    }
    return sum;
}

我(意思是 gcc)为 64 位想出了这个代码:

add(double*, double*, unsigned long):
        xor     eax, eax
        xorps   xmm0, xmm0
.L3:
        cmp     rdx, rax
        je      .L1
        addsd   xmm0, QWORD PTR [rdi+rax*8]
        addsd   xmm0, QWORD PTR [rsi+rax*8]
        inc     rax
        jmp     .L3
.L1:
        ret

这是 32 位 i386 的:

add(double*, double*, unsigned int):
        push    ebp
        xor     eax, eax
        fldz
        mov     ebp, esp
        mov     ecx, DWORD PTR [ebp+8]
        mov     edx, DWORD PTR [ebp+12]
.L3:
        cmp     DWORD PTR [ebp+16], eax
        je      .L1
        fadd    QWORD PTR [ecx+eax*8]
        fadd    QWORD PTR [edx+eax*8]
        inc     eax
        jmp     .L3
.L1:
        pop     ebp
        ret