Вставка константы в блок кода asm - PullRequest
2 голосов
/ 08 января 2012

У меня есть этот C макрос:

#define syscall(number) \
({ \
    asm volatile ( \
        ".set noreorder\n" \
        "nop\n" \
        "syscall "#number"\n" \
    );\
})

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

 syscall(5);

Однако, когда я делаю что-то подобное:

 #define SYSCALL_PUTC 5

 syscall(SYSCALL_PUTC);

Я получаю эту ошибку:

Ошибка: системный вызов инструкции требует абсолютного выражения

Как обойти это? Я не хочу, чтобы мой код был завален магическими числами.

Ответы [ 2 ]

4 голосов
/ 08 января 2012

Используйте stringification как это:

#define xstr(s) str(s)
#define str(s) #s
#define syscall(number) \
({ \
    asm volatile ( \
        ".set noreorder\n" \
        "nop\n" \
        "syscall "xstr(number)"\n" \
    );\
})

Для получения дополнительной информации о строковом преобразовании см. Эту страницу gcc:

http://gcc.gnu.org/onlinedocs/cpp/Stringification.html

0 голосов
/ 08 января 2012

Немного взлома, но не слишком: сделайте копию вашего оригинального макроса системного вызова для каждого номера системного вызова, назвав каждый для этого системного вызова. Таким образом, у вас будет макрос с именем SYSCALL_PUTC, который расширится до того же уровня, что и syscall (5).

...