使用 x86 程序集对数组中的元素求和

Sum elements in array using x86 assembly

我试图将总和存储在 edx 寄存器中,但输出显示为 0。如何解决此问题?

int main() {

   float price[ ] = { 22.1, 34.44, 567.33, 2.45 };
   float sum = 0;


   __asm {

                        xor eax, eax; //counter
                        mov ebx, 4 //num elements in array
                        lea ecx, price //address of first element in array
                        xor edx, edx //store sum
                    L1 :
                        add edx, [ecx+eax*4]
                        cmp eax, ebx
                        je done

                        inc eax
                        jmp L1

                    done :
                        mov sum, edx    
   }

   cout << "sum= " << sum; 

   return 0
}

add为整数相加;你想要 addss xmm0, [ecx+eax*4],最后有一个 movss 商店。在循环之前使用 xorps xmm0,xmm0 将 xmm0 归零,就像您使用 xor edx,edx 将整数寄存器归零一样。

(查看来自纯 C++ 循环的未优化或稍微优化的编译器输出,了解如何使用这些语法,如果您不确定。例如,在调试器中或 https://godbolt.org/


将这 4 个位模式相加得到的整数可能表示(作为 binary32 IEEE 浮点数)一个非常小的 float,恰好打印 0.0

如果需要完整的详细信息,请在单步执行时使用调试器查看寄存器和变量值。

根据 Peter 的回答,这段代码还有一个问题来自您的循环计数器。 eax 开始时为 0,这意味着它将通过循环(0、1、2、3、4)进行 5 次传递以使其等于 ebx,这意味着它在 price 结束后添加一些垃圾值.

我在浮点数后面添加了 f 后缀以消除编译器警告,但这并不是真正的因素。

#include <iostream>
using namespace std;

int main() {

    float price[] = { 22.1f, 34.44f, 567.33f, 2.45f };
    float sum = 0;

    __asm {

        xor eax, eax; //counter
        mov ebx, 4 //num elements in array
        lea ecx, price //address of first element in array
        xorps xmm0, xmm0

        L1 :
        addss xmm0, [ecx + eax * 4]
        dec ebx
        jz done

        inc eax
        jmp L1

        done :
        movss sum, xmm0
    }

    cout << "sum= " << sum;

    return 0;
}

可以做更多的事情来改进这段代码,但这会产生正确的答案。