【问题标题】:For-loop macro/preprocessor for assembly files in GCCGCC中汇编文件的for循环宏/预处理器
【发布时间】:2018-06-17 22:42:13
【问题描述】:

我相当肯定我以前在代码中看到过这一点,但我找不到任何关于如何做到这一点的参考资料。我确实希望这是特定于编译器或汇编器的。

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

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

然后可以像这样手动定义这些:

irq 0
irq 1
irq 2
...

但是,我不希望通过手动定义其中的 256 个来弄乱我的 ASM 文件。因此,我想做的是使用像预处理器/宏这样的 for 循环,它可以让我做这样的事情:

for i in 0 ... 255
    irq i

这可以通过使用宏来完成吗?

【问题讨论】:

  • rept 怎么样。请注意,这和您展示的是 gnu 汇编器 (gas) 的汇编器指令,因此与 gcc 或预处理器无关。
  • 虽然@Jester 或多或少是正确的,但与 GCC 和程序集之间存在关系,因为 GCC 将充当运行 as(gnu 汇编程序)的前端。有些人确实错误地认为这意味着 GCC 也是一个汇编程序。
  • 您可以执行类似.altmacro .set i, 0 .rept 256 irq %i .set i, i + 1 .endr 之类的操作。此处需要.altmacro 指令才能使其工作
  • @MichaelPetch 这似乎可以解决问题。我会回来报告的。 .altmacro 不常见吗
  • .altmacro 的使用在 GAS 开发人员中并不少见(有人可能会争辩说 GAS 在一般的装配开发中并不常见)。它是documented,供使用 GAS 的开发人员使用。我在自己的项目中使用过它。我们在这里使用.almacro,因此我们可以利用表达式结果作为字符串您可以编写'%expr'来评估表达式expr并将结果用作字符串。

标签: gcc assembly macros preprocessor


【解决方案1】:

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

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

.macro irq_stubX number
    irq\number:
    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 irq\number
.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's 建议,可以使解决方案更小更清晰。

.altmacro

.macro irq_insertX number
    .section .text
    irq_stubX \number

    .section .data
    .long irq\number
.endm

.section .data
default_handlers:
.set i,0
.rept 256
    irq_insertX %i
    .set i, i+1
.endr

【讨论】:

  • 您可以将irq_stubXirq_labelX 合并到一个宏中,并且只使用一个.rept 循环,方法是将节指令移动到统一宏中。
  • @RossRidge 更新了答案。不错的补充!效果很好。
  • IDK 为什么你认为.long irq %i 会起作用。 .long 指令采用数字表达式列表并将这些字节直接组合到输出文件中。它不接受指令助记符。你回答的那部分似乎让人分心。您可能希望将其移动到底部的单独部分。顺便说一句,回复:*UND* and *ABS* 部分的内容,请参阅stackoverflow.com/a/46870205/224132。所有符号都有一个关联的部分。不过,我不确定.long irq %i 会尝试评估什么,但没有逗号。
  • @PeterCordes 我对.long irq %i 的使用是尝试评估表示先前插入代码的标签的表达式。如图所示,由于存根标签和宏名称之间的名称共享,这有点令人困惑。这就是为什么我重命名存根宏 irq_stubX 并尝试使用 .long irq %i 生成 .long irq0(或 irq1 等),但无法使其正常工作。 default_handlers 符号旨在反映指向这些存根函数的指针数组。
猜你喜欢
  • 2011-09-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-16
  • 2019-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多