2014-10-12 3 views
1

Я пытаюсь научиться писать сборку gcc inline.Ошибка с сборкой gcc inline

Следующий код должен выполнять команду shl и возвращать результат.

#include <stdio.h> 
#include <inttypes.h> 

uint64_t rotate(uint64_t x, int b) 
{ 
    int left = x; 
    __asm__ ("shl %1, %0" 
      :"=r"(left) 
      :"i"(b), "0"(left)); 

    return left; 
} 

int main() 
{ 
    uint64_t a = 1000000000; 
    uint64_t res = rotate(a, 10); 
    printf("%llu\n", res); 
    return 0; 
} 

компиляция завершается с error: impossible constraint in asm

Проблема является в основном с "i"(b). Я пробовал "o", "n", "m" среди других, но он все еще не работает. Либо эта ошибка, либо operand size mismatch.

Что я делаю неправильно?

ответ

4

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

#include <stdio.h> 
#include <inttypes.h> 

uint64_t rotate(uint64_t x, int b) 
{ 
    __asm__ ("shl %b[shift], %[value]" 
      : [value] "+r"(x) 
      : [shift] "Jc"(b) 
      : "cc"); 

    return x; 
} 

int main(int argc, char *argv[]) 
{ 
    uint64_t a = 1000000000; 
    uint64_t res = rotate(a, 10); 
    printf("%llu\n", res); 
    return 0; 
} 

Обратите внимание, что «J» - для 64-битной. Если вы используете 32bit, «I» - правильное значение.

Другие вещи примечания:

  • Вы усечение ваше значение поворота от uint64_t к Int? Вы компилируете для 32-битного кода? Я не верю, что shl может делать 64-битные вращения при компиляции 32 бит.
  • Разрешение 'c' на ограничение ввода означает, что вы можете использовать переменные величины вращения (т.е. не жестко закодированные во время компиляции).
  • Поскольку shl изменяет флаги, используйте «cc», чтобы сообщить компилятору.
  • Использование формы [name] упрощает чтение asm (IMO).
  • % b является модификатором. См https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#i386Operandmodifiers

Если вы действительно хотите получить смекалку инлайн ассемблера, проверить последние Gcc документов: https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html

Смежные вопросы