我相当确定我以前在代码中看到过这个,但我找不到任何关于如何做到这一点的参考。我确实希望这是特定于编译器或汇编程序的。
我想定义一个(编译时(固定长度的函数指针数组,用作嵌入式设备上的中断向量表。每个处理程序将在跳转到公共处理程序之前推送其中断号。为这些更简单的函数创建宏非常简单:
.macro irq number
.global irqnumber
irqnumber:
pushd $number
jmp irq_handler_common
.endm
然后可以像这样手动定义这些:
irq 0
irq 1
irq 2
...
但是,我宁愿不要通过手动定义其中的 256 个来弄乱我的 ASM 文件。因此,我想做的是使用像预处理器/宏这样的 for 循环,这将允许我做这样的事情:
for i in 0 ... 255
irq i
这可以在使用宏中完成吗?
使用@MichaelPetch和@Jester的建议,我编译了以下工作解决方案(需要使用GNU汇编程序进行altmacro
,或其他支持汇编程序(。不幸的是,我必须创建两个宏,一个用于实例化中断入口点存根,另一个用于帮助创建这些入口地址的向量。我正在观察Error: invalid operands (*UND* and *ABS* sections) for %
是否尝试从创建default_handlers
的.rept
中使用.long irq %i
。如果有人有更小/更简单的解决方案,请发布!
定义特定于每个处理程序条目的入口点
.macro irq_stubX number
irqnumber:
pushd $number
jmp irq_handler_common
.endm
使用此宏(和altmacro
(,创建 256 个实例
.altmacro
.section .text
.set i,0
.rept 256
irq_stubX %i
.set i,i+1
.endr
最后,使用另一个宏,创建我们上面刚刚创建的标签的向量。
.section .data
.macro irq_labelX number
.long irqnumber
.endm
default_handlers:
.set i,0
.rept 256
irq_labelX %i
.set i, i+1
.endr
作为参考,这不起作用并报告上述错误:
default_handlers:
.set i,0
.rept 256
.long irq %i
.set i, i+1
.endr
编辑。根据下面的@RossRidge建议,解决方案可以做得更小、更清晰。
.altmacro
.macro irq_insertX number
.section .text
irq_stubX number
.section .data
.long irqnumber
.endm
.section .data
default_handlers:
.set i,0
.rept 256
irq_insertX %i
.set i, i+1
.endr