ошибка: невозможно зарегистрировать ограничение в «asm» - PullRequest
1 голос
/ 07 декабря 2011

Я столкнулся с проблемой при компиляции пакета, я не действительно хороший кодер, но я попытался исправить это для себя, и он все равно не скомпилируется. Это оригинальная часть кода.

#ifdef __GNUC__
asm("and $3, %%ecx;"
"shl $3 ,%%ecx;"
"ror %%cl, %0"
: "=r" (value)
: "r" (value), "c" (address));
#else

Ошибка:.

GBAinline.h: 139: ошибка: невозможно зарегистрировать ограничение в «asm» (строка ifdef 138)

И вот как я пытался заставить его выглядеть.

#ifdef __GNUC__
asm ("and $3 %%ecx,shl $3 %%ecx,ror %%cl, %0" : "=r" (value): "r" (value), "c" (address));

#else

Тем не менее, это не будет работать. Это эмулятор gba, прежде чем кто-либо спросит, VBA, и это часть GBAinline.h. Этот ассемблер уже сводит меня с ума.

Ред.: Проблема выше была хорошо обработана, я просто не обращал внимания на что компилятор, который я использовал. Но теперь я получаю эту ошибку на этот бит кода из заголовочного файла, я положил его на pastebin, чтобы все было немного более аккуратно ... (Извините, если это не так, я могу изменить это позже)

Это заголовок, в котором есть строки, которые приводят к ошибкам .: http://pastebin.com/k3D4cg0d

И это файл C, к которому он относится. http://pastebin.com/Ymg1X5dg

Это выдает ошибку, подобную этой .:

/var/tmp/cc3zA0lH.s: Assembler messages: /var/tmp/cc3zA0lH.s:69: Error: bad instruction `sw $3,0(r3)',

И так далее для остальных строк.

1 Ответ

1 голос
/ 07 декабря 2011

Эта встроенная сборка содержит ошибки:

  1. Он использует многострочные строки, которые эффективно объединяются. Без \n все отображается в одной строке. Независимо от того, принимает ли ваш ассемблер операторы , разделенные точками с запятой, все это имеет значение ... некоторые могут этого не делать.
  2. Указывает ту же переменную, что и ограничение ввода / вывода, вместо использования "+r"(value), как обычно предлагается для этой ситуации.

Не видя остальную часть кода, не совсем понятно, почему оператор встроенной сборки выглядит так, как он; Лично я бы предложил написать так:

asm("ror %%cl, %0" : "+r"(value) : "c"((((uintptr_t)address) & 3) << 3)));

потому что в сборке нет необходимости выполнять сами расчеты. uintptr_t (из <stdint.h>) также делает это агностиком 32/64-битное.

Edit:

Если вы хотите его для другого ЦП, кроме x86 / x64, то, очевидно, он должен быть другим ... Для ARM ( не Thumb2) это будет:

asm("ROR %0, %0, %1" : "+r"(value) : "r"((((uintptr_t)address) & 3) << 3)));

так как там действует инструкция поворота.

Редактировать (добавить ссылку):

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

(a >> shift | a << (8 * sizeof(a) - shift))

как для встроенного x86

asm("ror %%cl, %0" : "+r"(a) : "c"(shift))

Проверка этого:

#include <stdint.h>

int main(int argc, char **argv)
{
    unsigned int shift = (int)((((uintptr_t)argv) & 3) << 3);
    unsigned int a = argc;
#ifdef USE_ASM
    /*
     * Mark the assembly version with a "nop" instruction in output
     */
    asm("nop\n\t"
        "ror        %%cl, %0" : "+r"(a) : "c"(shift));
    return a;
#else
    return (a >> shift | a << (8 * sizeof(a) - shift));
#endif
}

Скомпилируйте / разберите его:

$ gcc -DUSE_ASM -O8 -c tf.c; objdump -d tf.o

tf.o:     file format elf64-x86-64

Disassembly of section .text:

0000000000000000 :
   0:   83 e6 03                and    $0x3,%esi
   3:   8d 0c f5 00 00 00 00    lea    0x0(,%rsi,8),%ecx
   a:   90                      nop
   b:   d3 cf                   ror    %cl,%edi
   d:   89 f8                   mov    %edi,%eax
   f:   c3                      retq
$ gcc -O8 -c tf.c; objdump -d tf.o

tf.o:     file format elf64-x86-64

Disassembly of section .text:

0000000000000000 :
   0:   83 e6 03                and    $0x3,%esi
   3:   8d 0c f5 00 00 00 00    lea    0x0(,%rsi,8),%ecx
   a:   d3 cf                   ror    %cl,%edi
   c:   89 f8                   mov    %edi,%eax
   e:   c3                      retq

Ergo, эта встроенная сборка не нужна.

...