Добавление массива во встроенную сборку x86? - PullRequest
1 голос
/ 12 февраля 2011

Я новичок в кодировании ассемблера и встраивании его в C ++. Я пытаюсь добавить целые числа в массив с использованием ассемблера.Это код, который у меня пока есть:

#include <iostream>
#include <stdio.h>
int x [] = {5,4,3,2,1};
int sumArray(int [5]);
int main()
{
    sumArray(x);
    printf_s("The sum of the array is %d");
}
int sumArray(int [5])
{
    __asm
    {
        mov edi,OFFSET sumArray
        mov ecx,5
        mov eax,0
    L1:
        add eax,[edi]
        add edi, TYPE sumArray
        loop L1
    }
}

Первоначальная проблема, с которой я столкнулся, была с mov ecx У меня было это как

mov ecx,LENGTHOF sumArray

но он не скомпилируется, поэтому я изменил его на 5, и он скомпилировался.Так что теперь, когда я запускаю программу, она ломается.Я использовал F11 в Visual Studio, чтобы переходить строка за строкой, чтобы увидеть, на какой строке программа разрывается, и программа разрывается при повторном прохождении цикла.

Так что, если кто-то может помочь мне понять, как я могуЯ позабочусь об этом.

Ответы [ 2 ]

2 голосов
/ 12 февраля 2011

Мне кажется, у вас это сломалось совсем немного.Прежде всего, у вас есть функция с именем sumArray с аргументом без имени .Но внутри функции вы ссылаетесь на sumArray, как если бы это было имя аргумента массива.Затем вам нужно понять, как C (++) передает массивы в качестве аргументов: они (всегда) передаются по ссылке, как указатель на первый член массива.И это также означает, что функция (в общем случае) не знает длину массива (если вы не установите его в фиксированный размер).Таким образом, вы обычно передаете длину в другом аргументе.Это означает, что у нас есть следующее:

int sumArray(int arr[], int len)
{
    __asm
    {
        mov edi, arr
        mov ecx, len
        xor eax, eax
    L1:
        add eax, [edi]
        add edi, 4
        loop L1
    }
}

Обратите внимание, что мы не пытаемся получить смещение массива, которое бы привело нас к указателю, нам нужно получить значениеуказателя, то есть адрес первого элемента массива.Также обратите внимание, что я жестко закодировал размер элемента (4), нет смысла действовать так, как будто мы можем работать с чем угодно, если в предыдущей строке мы добавим 32-битные слова.(xor eax, eax - это просто еще один способ установить регистр на ноль, если честно, в современных процессорах я не уверен, работает ли он быстрее или нет.)

И при тестировании не забывайтефактически передать результат в printf_s

1 голос
/ 12 февраля 2011

Проблема с вашим кодом, кажется, заключается в том, что вы используете sumArray имя вашей функции вместо вашего фактического массива x, и именно поэтому он вылетает.

Разве ваш асм не должен выглядеть так:

__asm
{
    mov edi,OFFSET x
    mov ecx,LENGTHOF x
    mov eax,0
L1:
    add eax,[edi]
    add edi, TYPE x
    loop L1
}

? (здесь я предполагаю, что вы не ошиблись насчет использования макросов, поскольку я никогда не компилировал ничего, используя MASM, который, кажется, используется здесь, но я думаю, что вы поняли)

Другой вопрос заключается в том, почему вы передаете безымянный аргумент sumArray, если вы на самом деле его не используете, лучше передать массив в качестве именованного аргумента и его длину и использовать их в коде сборки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...