2016-02-10 4 views
0

У меня следующая проблема: я хочу использовать следующий код ассемблера из моих C исходных файлов, используя встроенный ассемблер:Встроенный ассемблер: Передаёт константа

.word 1 

Ближайший я получил использует этот встроенный ассемблер код:

asm(".word %0\n": : "i"(1)); 

Однако это приводит к следующему коду в созданном файле ассемблера:

.word #1 

Так что мне нужен способ передать константу, которая известна во время компиляции, не добавляя перед ней «#». Возможно ли это с помощью встроенного ассемблера?

Edit:

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

#define LABELS_PUT(b) asm(".word %0\n": : "i"((b))); 

int func(void) { 
    LABELS_PUT(1 + 2); 

    return 0; 
} 

Я не могу использовать».word 1" , так как значение будут отличаться при каждом вызове макроса LABELS_PUT.

+1

RTFM. Что случилось с 'asm (". Word 1 \ n ":: :);'? Пожалуйста, прочитайте документацию и/или учебник. – Olaf

+0

Это для ARM? Это что-то, что вы не можете сделать более легко с помощью компилируемого отдельно .s? –

+0

Я отредактировал вопрос, чтобы понять, почему я не могу использовать «.word 1» – lkamp

ответ

1

У вашего макроса есть ; в конце. Так что это целое утверждение, а не просто выражение. Не делай этого.

A .word Смешанный с кодом вашей функции, как правило, будет незаконной инструкцией, не так ли? Вы на самом деле планируете запустить этот двоичный файл?


Вы должны быть в состоянии получить препроцессор stringify your macro parameter, и пусть строка-конкатенации присоединиться к его. Затем ассемблер может оценить 1+2.

#define LABELS_PUT(b) asm(".word " #b "\n") 


LABELS_PUT(1+2); // becomes: 
asm(".word " "1+2" "\n"); 

Там также https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#x86Operandmodifiers, некоторые из которых могут работать для других архитектур:

asm (".word %c0" : : "i" (b)) 
+0

Большое спасибо, это выглядит очень многообещающе. Я рассмотрю два варианта. – lkamp

0

В GCC вы можете сделать это следующим образом:

asm __volatile__ (".word 0x1"); 

Если вы используете Visual Studio, то вы можете попробовать:

some_word: _asm{_emit 1000b} 

Он будет проходить в кодовое слово постоянной 1000b

Вы можете получить доступ с ярлыком some_word

+0

'volatile' [подразумевается для операторов asm GNU C без выходов] (https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Volatile).Вот почему я не использовал его в своем ответе. –

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