Страницы

Поиск по вопросам

среда, 22 января 2020 г.

Как сделать правильную ассемблерную вставку

#cpp #c #ассемблер #gcc


Хочу попрактиковаться с ассемблерными вставками. Хотел написать код для вычисления
суммы чисел от 1 до n, реализуя это на ассемблере. Однако пока не смог скомпилировать
даже простой код записывающий в sum значение n. Вот код:

#include 
int sumN(int n)
{
    // calculate 1+2+...+n
    int sum;
    __asm__(
        "mov %1, %eax\n\t"
        "mov %eax, %0\n\t"
        :"=d"(sum)
        :"c"(n)
        :"%eax");
    return sum;
}
int main()
{
    for (int i = 1; i < 100; ++i)
    {
        printf("n: %d sum(n): %d\n",i,sumN(i) );
    }
    return 0;
}


Однако компилятор g++ выдает ошибку 


  main.cpp:11:11: error: invalid 'asm': operand number missing after
  %-letter                                                :"%eax");
  ^
  main.cpp:11:11: error: invalid 'asm': operand number missing after
  %-letter.


Думал что проблема в том что я не указал все регистры, которые я использую, поэтому
немного переписал код:

#include 
int sumN(int n)
{
    // calculate 1+2+...+n
    int sum;
    __asm__(
        "mov %1, %eax\n\t"
        "mov %eax, %0\n\t"
        :"=d"(sum)
        :"c"(n)
        :"%eax","%edx","%ecx");
    return sum;
}
int main()
{
    for (int i = 1; i < 100; ++i)
    {
        printf("n: %d sum(n): %d\n",i,sumN(i) );
    }
    return 0;
}


Однако и такой код не компилируется, gcc выдает ошибку 


  main.cpp:11:25: error: ‘asm’ operand has impossible constraints
  :"%eax","%edx","%ecx");


Подскажите, в чем ошибка и как ее исправить?
P.S. руководствовался вот этой статьей
    


Ответы

Ответ 1



В самом ассемблерном коде надо знак % экранировать, т.е. писать %%eax, а вот в clobber-списке, наоборот, знак % необязателен. int sumN(int n) { // calculate 1+2+...+n int sum; __asm__( "mov %1, %%eax\n\t" "mov %%eax, %0\n\t" :"=d"(sum) :"c"(n) :"eax"); return sum; } ... $ gcc test.c -m32 -o test $ ./test n: 1 sum(n): 1 ... n: 99 sum(n): 99 Кстати, учтите,что про компиляции под x86-64, запись в eax обнуляет старшие биты rax. Это надо будет отразить в clobber-списке.

Комментариев нет:

Отправить комментарий