2012-05-31 2 views
1

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

asm("" :: "r0" (value)); 
asm("" :: "a1" (value)); 

Обе линии будут вызывать:

Error: matching constraint references invalid operand number 

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

Почему я спрашиваю В настоящее время я работаю над некоторыми системными вызовами. Я хочу использовать макрос syscall следующим образом:

#define SYSCALL0(NUMBER) asm("swi #" STRINGIFY(NUMBER)); 
#define SYSCALL1(NUMBER, A) asm("swi #" STRINGIFY(NUMBER) :: "r0"(A)); 
#define SYSCALL2(NUMBER, A, B) asm("swi #" STRINGIFY(NUMBER) :: "r0"(A), "r1"(B)); 
... 

Как вы можете видеть, это идеально подходит для on-line. Конечно, я мог бы сделать что-то вроде:

#define SYSCALL1(NUMBER, A) register type R0 asm("r0") = A; 
          SYSCALL0(NUMBER) 

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

ответ

1

С GCC, есть ярлык:

register long r0 asm ("r0"); 

Тогда r0 "псевдонимы", регистрирующий.

Объедините это с statement expression, и вы даже можете получить r0 в качестве «возвращаемого значения».

#define SYSCALL1(NUMBER,A) ({\ 
    register long r0 asm("r0") = (long) (A); \ 
    asm("swi #" STRINGIFY(NUMBER) : "=r"(r0) : "r"(r0) : "memory"); \ 
    r0; }) 

(я понятия не имею, если колошматить является законным или нет, реализация системного вызова uClibc имеет то же.)

См extended assembly и local reg vars.

+0

Да, тот, который я знал, но мне не нравится длинный синтаксис. Я обновлю свой вопрос, чтобы показать свою мотивацию. – Nobody

+0

Не все ли регистры, с которыми вы имеете дело с тем же «C-типом» (длинным)? – Mat

+0

Регистры этого типа, но переменные, которые входят, могут иметь произвольные типы (например, int, char *, void (fn *) (void), ...), поэтому мне пришлось бы делать бросок каждый раз. Дело не в том, что это невозможно, но это действительно уродливо. – Nobody

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