Суммирование элементов в массиве с использованием сборки x86 - PullRequest
0 голосов
/ 08 апреля 2020

Я пытаюсь сохранить сумму в регистре 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
}

Ответы [ 2 ]

1 голос
/ 08 апреля 2020

Основываясь на ответе Питера, есть еще одна проблема с этим кодом, которая исходит от вашего счетчика l oop. eax начинается с 0, что означает, что он пройдет 5 проходов через l oop (0, 1, 2, 3, 4), чтобы он равнялся 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;
}

Для улучшения есть еще что-то этот код, но это дает правильный ответ.

0 голосов
/ 08 апреля 2020

add - целочисленное сложение; Вы хотите addss xmm0, [ecx+eax*4] и movss магазин в конце. Обнулите xmm0 с xorps xmm0,xmm0 перед l oop, как вы делали с xor edx,edx для обнуления целочисленного регистра.

(Посмотрите на неоптимизированный или слегка оптимизированный вывод компилятора из чистого C ++ l oop для синтаксиса о том, как использовать их, если вы не уверены, например, в отладчике или в https://godbolt.org/)


Целое число, которое получается в результате суммирования этих 4 бит -patterns в виде целых чисел, вероятно, представляют (как двоичный код 32 IEEE) очень маленький float, который происходит для печати 0.0

Используйте отладчик для просмотра значений регистров и переменных, пока вы делаете один шаг, если хотите полная информация.

...