【发布时间】:2013-01-31 01:15:10
【问题描述】:
与我的问题最接近的主题是Escaping a # symbol in a #define macro? 和How to print a pound / hash via C preprocessor?,但它们并不能完全回答我的问题。更明确地说,第二个似乎不适用于 armcc 编译器。它只打印 hash4 而不是 hash 定义的符号。 Chris Lutz 在第二篇文章中特别贬低了尝试使用宏来实现此功能,所以这可能是不正确的方法。不过,我想要更多的想法,而不仅仅是一个人。
问题如下:我正在尝试编写一个使用宏定义嵌入式 asm C 函数的宏。我基本上已经实现了它,除了一个问题......表达了一个直接的价值。立即值的语法需要(我相信)一个磅符号,它也是预处理器的“字符串化”符号。那么,是否可以在 C 宏中转义 # 符号?
这背后的主要目的是用 pico 内核线程上下文管理过程包装一个 isr,并且新过程的函数指针最终将传递给向量中断控制器。
代码如下:
#define ISR_THREAD_MGMT(ISR_FUNC,FUNC_NAME) \
__asm void FUNC_NAME ( void ); \
__asm void FUNC_NAME (void ) \
{ \
STMDB sp!, {r0-r3}; \
MRS r0, SPSR; \
SUB lr, lr, #4; \ <----- Heres the problem
STMDB sp!, {r0, r10, r12, lr}; \
bl _thread_vectored_context_save; \
bl ISR_FUNC; \
b _thread_context_restore; \
}
我希望我已经足够详细地解释了所有内容。如果没有,请不要犹豫,询问更多详细信息。
【问题讨论】:
-
我的第一直觉是“不要为此使用宏”,但显然你已经看到其他人这么说,所以我不确定你希望我们说什么 - 你是试图使用宏预处理器来做它从未设计过的事情。如果您使用的是 at&t 语法,那么 if 会神奇地工作,因为 $ [indication of constant] 不是预处理器“特殊字符”。一种解决方案当然是在单个函数中实际写出 FUNC_NAME 和 ISR_FUNC - 或者不将 C 编译器用于汇编代码......
-
总的来说,我想要一个比一个人的想法更大的共识。那么,您是说将嵌入式汇编指令指定为宏超出了其预期用途吗?宏最初不是为内联函数调用而编写的吗?此外,一个不允许您编写所有符号的文本预处理器?对我来说似乎很奇怪......
-
C 预处理器是为 C 设计的——它是它名字的一部分。在设计 C 时,内联汇编器不是范围的一部分——编译器会产生汇编器,然后通过系统汇编器进行汇编——如果你想自己添加汇编代码,你写了一个
something.s文件——它仍然是有效的选项。大多数汇编程序确实具有宏功能,可让您一遍又一遍地生成相同的代码,但有变体。 -
是的,我已经通过那个方法实现了它,我只是觉得因为 arm 有一个嵌入式汇编器,所以周围有额外的 asm 文件并不那么简洁。我只是觉得奇怪的是文本预处理器不允许您打印任何字符。为什么你认为限制?在解析器端易于编码?或者他们只是从未见过用例?
-
嗯,您的用例并不完全是“主流”,是吗?但是请务必联系 ARM 并说“请确保我可以使用您的预处理器使内联汇编器与 # 一起工作” - 他们可能会添加某种扩展。我没有看到操作系统中有“interrupts.s”或类似的东西作为“额外的 asm 文件”——这是我所期望的。 Linux 有它,Symbian OS 有它,据我所知,Windows 和 OSE 一样——还有一个用于 Xerox 的专有操作系统,我不记得它的名称 [但我移植了代码]。