I'm currently reading a tutorial on Raspberry Pi OS development and was wondering about the way local labels are used in this code snippet (GCC ARM Assembly):
...
b 2f
1:
stmia r4!, {r5-r8}
2:
cmp r4, r9
blo 1b
...
If you use 1:
as a label you have to specify either f
or b
after the jump instruction to make the assembler know in which direction the jump is aimed. As far as I know you could also use this:
...
b .2
.1:
stmia r4!, {r5-r8}
.2:
cmp r4, r9
blo .1
...
I think this option is a lot less confusing (local labels are also marked with a dot in x86 assembly), because there is no additional letter after the label reference. I have tested the resulting machine code and it's the same. So my questions:
Why would you use the one variant over the other?
Why is it necessary to specify the direction of the jump with either f
or b
?
答案 0 :(得分:8)
The important difference is that the numbered local labels can be reused without worry and that is why you need to specify the direction too. You can jump to preceding or following one, but not the ones beyond them.
1: foo
...
1: bar
...
jmp 1b # jumps to bar
...
jmp 1f # jumps to baz
...
1: baz
...
1: qux
...
jmp 1b # jumps to qux
As long as you only use them within a single block only, you can be sure they will work as intended and not conflict with anything else.
答案 1 :(得分:1)
本地标签的一个主要好处是,由于相同的标识符可以多次出现,因此可以在宏中使用它们。考虑一些假设的本地标签用法,但是:
.macro dothething rega regb ptr
ldrex \regb, [\ptr]
cmp \rega, \regb
beq 1
2: <more instructions>
...
strex \regb, \rega, [ptr]
cmp \regb, #0
bne 2
1:
.endm
myfunction:
dothething r0 r1 r2
dothething r0 r1 r3
bx lr
armasm实际上允许这种情况(尽管语法稍有不同),其中没有指定方向的行为是&#34;向后搜索,然后向前搜索&#34;,但仍然在任何合理的默认行为下,上述代码中的至少一个跳转将最终定位到标签的错误实例。在宏中用beq 1f
和bne 2b
明确地调出方向可以解决歧义,并在宏的两次调用中生成正确的跳转。
如果您选择使用的东西不是真正的本地标签,那么您不仅可能会使您的符号表与垃圾混乱,而且还会让您自己在宏中使用循环或条件分支。您生成非唯一符号。我的例子可能看起来有点人为,但是从汇编程序宏切换到C函数中的内联asm块,它们遍布复杂的代码库,things get a lot more real。