GCC

时间:2018-01-08 22:35:24

标签: gcc assembly macros preprocessor

我相当肯定我之前在代码中已经看过这个,但是我找不到任何关于如何做的参考。我确实希望这是编译器或汇编程序特定的。

我想定义一个(编译时)固定长度的函数指针数组,用作嵌入式设备上的中断向量表。每个处理程序将在跳转到公共处理程序之前推送其中断号。为这些更简单的函数创建宏是直截了当的:

.macro irq number
    .global irq\number
    irq\number:
    pushd $\number
    jmp irq_handler_common
.endm

然后可以手动定义这些:

irq 0
irq 1
irq 2
...

但是,我宁愿不通过手动定义其中的256个来混乱我的ASM文件。因此,我想要做的是使用像循环一样的预处理程序/宏,这将允许我做这样的事情:

for i in 0 ... 255
    irq i

可以使用宏来完成吗?

1 个答案:

答案 0 :(得分:4)

使用@MichaelPetch@Jester的建议我已经编译了以下工作解决方案(需要使用GNU汇编程序用于altmacro或其他支持汇编程序)。不幸的是,我不得不创建两个宏,一个用于实例化中断入口点存根,另一个用于帮助创建这些入口地址的向量。如果我尝试在创建Error: invalid operands (*UND* and *ABS* sections) for %的{​​{1}}内使用.long irq %i,我会观察.rept。如果有人有更小/更简单的解决方案,请发布!

定义特定于每个处理程序条目的入口点

default_handlers

使用此宏(和.macro irq_stubX number irq\number: pushd $\number jmp irq_handler_common .endm ),创建256个实例

altmacro

最后,使用另一个宏,创建我们刚才创建的标签的矢量。

.altmacro

.section .text
.set i,0
.rept 256
    irq_stubX %i
    .set i,i+1
.endr

作为参考,这不起作用并报告上述错误:

.section .data
.macro irq_labelX number
    .long irq\number
.endm

default_handlers:
.set i,0
.rept 256
    irq_labelX %i
    .set i, i+1
.endr

修改即可。根据以下@RossRidge's建议,可以使解决方案更小,更清晰。

default_handlers:
.set i,0
.rept 256
    .long irq %i
    .set i, i+1
.endr