我需要编写一个需要内联汇编的宏
#define create_me(name) \
__asm\
mov name,#0x1021\
__endasm\
# 但是没有编译。我尝试将它作为参数传递,但这也不起作用。它说无效的预处理器令牌。我可以尝试使用内联函数,但无法动态创建寄存器名称。那就是我无权访问 name 变量。有没有人对如何在宏中使用 # 操作有任何建议。
我看过在#define 宏中转义# 符号?,但我已经清楚地解释了为什么我需要这里的宏。我的用例不同。
我需要编写一个需要内联汇编的宏
#define create_me(name) \
__asm\
mov name,#0x1021\
__endasm\
# 但是没有编译。我尝试将它作为参数传递,但这也不起作用。它说无效的预处理器令牌。我可以尝试使用内联函数,但无法动态创建寄存器名称。那就是我无权访问 name 变量。有没有人对如何在宏中使用 # 操作有任何建议。
我看过在#define 宏中转义# 符号?,但我已经清楚地解释了为什么我需要这里的宏。我的用例不同。
通过另一个宏使用间接应该可以解决问题:
#define HASH_LIT #
#define HASH() HASH_LIT
#define create_me(name) \
__asm\
mov name,HASH()0x1021\
__endasm
对于 SDCC,请使用新__asm__
格式。
#define create_me(name) \
__asm__( "mov " #name ", #0x1021" )
预处理器命令/指令始终以尖号 ( ) 开头#
,您不能将其用于您自己的符号。
如果要创建一个名为的变量,请whatever0x1021
使用标记串联 ##
:
#include <stdio.h>
#define create_me(name) name ## 0x121
int main(void)
{
int create_me(a); /* int a0x121; */
return 0;
}
它有助于理解问题的本质。该#
符号在三个方面对预处理器来说是特殊的:
预处理器将其第一个预处理标记的源代码行#
识别为不是“文本行”。也就是说,它包含预处理器的指令。另一方面,文本行是要处理的数据——主要是 C 程序源,但可能包含要扩展的宏。#
如果它不是行上的第一个预处理标记,则在这个意义上它并不特殊。
在类函数宏的替换列表的预处理标记中,标记#
是字符串化运算符。但是,它不适用于类似变量的宏,也不适用于重新扫描宏扩展文本以进行进一步的宏替换。
在类函数宏的替换列表的预处理标记中,标记##
是标记粘贴运算符。但是,它不适用于类似变量的宏,也不适用于重新扫描宏扩展文本以进行进一步的宏替换。
正如@Quentin 演示的那样,您无法逃避对#
预处理器本身的重要性,但是您仍然可以通过使用一些间接来实现所需的宏。首先,如果 a#
出现在类似函数的宏的扩展中,那么它不能直接出现在该宏的替换文本中,在那里它将被解释为字符串化运算符。相反,它必须通过扩展另一个宏来引入。其次,如果它必须与其他没有空格的文本相邻,那么扩展到它的直接宏必须是类似函数的宏本身,以便括号用于将宏名称与相邻文本分开。这需要第二级间接。