Простой пример сборки: установка входных данных и получение выходных данных — правильный синтаксис

Я пытаюсь сделать простой пример, чтобы вставить в код C 32-битный фрагмент сборки Sparc; этот небольшой код выполняет приращение переменной «сумма».

Код:

#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>

int n;
int sum;

int main ()
{
  n = 100;
  sum = 0;

  struct timeval tv1, tv2;
  long long diff;

  gettimeofday (&tv1, NULL);

  asm volatile ("set sum, %g1\n\t" \
                "set n, %g3\n" \
                "loop:\n\t" \
                "add %g1, 1, %g2\n\t" \
                "sub %g3, 1, %g4\n\t" \
                "bne loop\n\t" \
                "nop\n\t" \
                : "=r" (sum)
                : "r" (n)
                );

  gettimeofday (&tv2, NULL);

  diff = (tv2.tv_sec - tv1.tv_sec) * 1000000L + (tv2.tv_usec - tv1.tv_usec);
  printf ("Elapsed time = %d usec\n", diff);

  printf ("Sum = %d\n", sum);

  return 0;

}

К сожалению, компиляция с помощью gcc4.1.2 приводит к следующим ошибкам:

loop_dev_for-assembly_code.c: In function #main#:
loop_dev_for-assembly_code.c:18: error: invalid 'asm': invalid operand output code
loop_dev_for-assembly_code.c:18: error: invalid 'asm': operand number out of range
loop_dev_for-assembly_code.c:18: error: invalid 'asm': invalid operand output code
loop_dev_for-assembly_code.c:18: error: invalid 'asm': operand number out of range
loop_dev_for-assembly_code.c:18: error: invalid 'asm': operand number out of range
loop_dev_for-assembly_code.c:18: error: invalid 'asm': operand number out of range

Кажется, строка 18 соответствует "asm volatile ("set sum, %g1\n\t" \ ...".

Но я не знаю, как обойти эти ошибки. Это может происходить из переменной sum, которая установлена ​​в регистре %g1.

О связях между переменной, принадлежащей коду C, и переменной, локализованной в части кода на ассемблере. Я также видел для входных и выходных параметров синтаксис "=g" (выходной параметр ??), "g" (входной параметр): я думаю, что он соответствует разным регистрам между двумя синтаксисами.

если бы кто-нибудь мог дать мне некоторые подсказки, чтобы понять эту ссылку и отладить мой небольшой код, который выполняет простой цикл для увеличения variable sum.

Спасибо за помощь, с уважением.


person youpilat13    schedule 18.05.2017    source источник
comment
Вы пробовали читать инструкцию? Ты сделал так много ошибок, что трудно сосчитать. В любом случае, по возможности избегайте встроенного ассемблера и используйте отдельный ассемблерный файл.   -  person Jester    schedule 19.05.2017
comment
-@Jester Извините, я давно не практиковал ассемблер Sparc и особенно встроенный ассемблер. Если бы вы могли указать несколько больших ошибок в маленьком встроенном коде.   -  person youpilat13    schedule 19.05.2017
comment
Вы используете gcc, ориентированный на sparc, или, например, это x86 gcc, который вы загружаете sparc? в первую очередь уберите ассемблер в свой файл и вызовите gcc или as для его сборки, затем оберните его меткой и вернитесь и вызовите его из Си.   -  person old_timer    schedule 19.05.2017
comment
Я компилирую из версии Debian Etch для Sparc (32-разрядная версия Sparc), и эта версия Sparc работает благодаря QEMU с командой qemu-system-sparc на хосте QEMU, а также с образом Debian Etch. Если бы вы могли назвать мне основные ошибки встроенного кода, это было бы прекрасно. С Уважением   -  person youpilat13    schedule 19.05.2017
comment
tldp.org/HOWTO/html_single/Assembly-HOWTO   -  person Cody Gray    schedule 19.05.2017


Ответы (1)


Как кто-то еще сказал, в вашем встроенном ассемблерном коде много ошибок и неправильных представлений. Вот лишь несколько вещей. Во-первых, в расширенном синтаксисе ассемблера вы должны экранировать все символы «%» другим «%», поэтому, например, вам нужно поставить «%% g1» вместо «% g1» и сделать это для всех регистров, к которым вы обращаетесь. Во-вторых, вы не можете использовать 'set' ни для одной из переменных n или sum, так как обе они являются переменными стека, а не глобальными. Вы уже объявили эти переменные в качестве позиционных параметров в своем операторе asm, поэтому сумма — это параметр %0, а n — %1. Ваша инструкция добавления помещает результат в %g2, который никогда нигде не инициализируется и не используется.

Я думаю, что всю последовательность можно было бы визуализировать намного проще, как это (не проверено):

 asm volatile ("clr %%g1\n" \
            "loop:\n\t" \
            "add %%g1, 1, %%g1\n\t" \
            "subcc %1, 1, %1\n\t" \
            "bne loop\n\t" \
            "nop\n\t" \
            "mov %%g1, %0\n" \
            : "=r" (sum)
            : "r" (n)
            : "g1" );
person Rob Gardner    schedule 20.05.2017