如何在 MPLAB X 中使用 mips 汇编为每个宏调用创建唯一标签

How can one create a unique label for each macro call using mips assembly in MPLAB X

我有一个执行比较的宏,如果比较不正确则跳转到宏的末尾。这是一个简化的例子:

.macro do_work_if_value_not_zero value
    li s0, value
    bne s0, zero, exit_label
    nop   

    // Do work

    exit_label:
.endm

然而,问题是我多次调用这个宏,如下所示:

do_work_if_value_not_zero 5
do_work_if_value_not_zero 3
do_work_if_value_not_zero 12

因此我收到以下错误:

Error: symbol `exit_label' is already defined



因为我从不多次调用具有相同参数的宏,所以我尝试使用与“:”连接的参数名称来创建一个唯一的标签,如下所示:

.macro do_work_if_value_not_zero value
    li s0, value
    bne s0, zero, \value
    nop   

    // Do work

    \value:
.endm

但这似乎不起作用,我收到了更多错误。

因此我的问题是,如何为每个宏调用创建一个唯一的退出标签来避免这个问题?

@markgz 的回答是最好的

如果需要替代解决方案,我会保留此答案


这里的问题是 value 不能用作标签,因为它是一个数字。因此,它可能不包含我们想要跳转到的行号。

这个问题有两种解决方法。

第一

我们可以将文本连接到 value 以使其成为像这样的正确标签名称

exitLabel\value :

第二(由@Christian Gibbons 提供)

我们可以像这样添加另一个参数来指定标签名称

.macro do_work_if_value_not_zero value exitLabelName
    ...
    ...
\exitLabelName :

这个解决方案意味着可以多次调用具有相同参数的宏,这与第一个解决方案不同,第一个解决方案仅限于对宏的唯一调用。

大多数汇编器允许这样的本地标签:

.macro do_work_if_value_not_zero 
    li s0, value
    bne s0, zero, 1f     # 1f means branch forward to the next label '1:'
    nop   

    // Do work

    1:
.endm

来自 MIPS 汇编程序手册 here:

A generated label is a single numeric value (1...255). To reference a generated label, put an f (forward) or a b (backward) immediately after the digit. The reference tells the assembler to look for the nearest generated label that corresponds to the number in the lexically forward or backward direction.