2016-07-07 3 views
2

мне нужно написать макрос, который нужно встроенный ассемблерКак избежать # в макро

#define create_me(name) \ 
    __asm\ 
    mov name,#0x1021\ 
    __endasm\ 

# однако не компиляции. Я попытался передать его как параметр, но это тоже не работает. В нем указан недопустимый токен препроцессора. Я могу попытаться использовать встроенную функцию, но я не могу динамически создавать имя регистра. То есть у меня нет доступа к переменной имени. У кого-нибудь есть предложения по использованию операции # внутри макроса.

Я посмотрел Escaping a # symbol in a #define macro?, но я ясно объяснил, зачем мне нужен макрос здесь. Мой учет - это другое.

+0

Какой компилятор? – Neil

+0

SDCC, думаю. http://sdcc.sourceforge.net/ – ecatmur

+0

Да. SDCC версия 3.5 – losang

ответ

4

Использование косвенность через другой макрос должен сделать трюк:

#define HASH_LIT # 
#define HASH() HASH_LIT 

#define create_me(name) \ 
    __asm\ 
    mov name,HASH()0x1021\ 
    __endasm 
+0

Я не пробовал. Позвольте мне посмотреть, если он компилирует – losang

+0

Нет, не получится. –

+0

@losang Это было из памяти, и я забыл ее половину. Вот рабочая версия. – Quentin

0

Команды/директивы препроцессора всегда начинаются с резкого знака (#), вы не можете использовать его для собственных символов.

Если вы хотите создать переменную с именем whatever0x1021 использовать token concatenation##:

#include <stdio.h> 

#define create_me(name) name ## 0x121 

int main(void) 
{ 
    int create_me(a); /* int a0x121; */ 

    return 0; 
} 
+0

Идея заключается не в создании переменной, а в переносе переменной с использованием встроенной сборки. – losang

2

Для SDCC, используйте новый __asm__ формат.

#define create_me(name) \ 
     __asm__("mov " #name ", #0x1021") 
0

Это помогает понять природу проблемы. # символ является специальным препроцессору тремя способами:

  1. Источник линия, первый предобработки маркер # распознается препроцессора не будучи «текстовая строка». То есть он содержит инструкции для препроцессора. С другой стороны, текстовые строки - это данные, которые нужно обработать, в основном источник программ C, но, возможно, содержащие макросы для расширения. # не является особенным в этом смысле, если это не первый токен предварительной обработки на линии.

  2. Среди токенов предварительной обработки списка заметок для функционально-подобного макроса токен # является оператором строкования. Тем не менее, это не служит этой цели в макромодульном макросе, а также при повторном сканировании текста с расширенным расширением для дальнейшей замены макросов.

  3. Среди токенов предварительной обработки списка заметок для функционально-подобного макроса токен ## является оператором маркера. Тем не менее, это не служит этой цели в макромодульном макросе, а также при повторном сканировании текста с расширенным расширением для дальнейшей замены макросов.

Вы не можете избежать значения # препроцессору самих по себе, но вы можете все-таки реализовать нужный макрос, используя немного косвенности, как показано @Quentin. Во-первых, если # должен появиться в расширении функционально-подобного макроса, то он не может появиться непосредственно в тексте замены этого макроса, где он будет интерпретироваться как оператор строкования. Вместо этого он должен быть введен путем расширения другого макроса. Во-вторых, если он должен упираться в другой текст без пробелов между ними, то ближайший макрос, который расширяется до него, должен быть сам макрокомпоновым макросом, так что в скобках используется разделение имени макроса от примыкающего текста. Это требует второго уровня косвенности.

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