简体   繁体   中英

ARM Assembly Local Labels

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 ?

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.

One of the main benefits of local labels is that since the same identifier can appear multiple times, they can be used in macros. Consider some hypothetical local label usage like this, though:

   .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

That's actually allowed in armasm (albeit with slightly different syntax), where the behaviour in the absence of a specified direction is "search backwards, then forwards", but still under any reasonable default behaviour at least one of the jumps in the above code is going to end up targeting the wrong instance of a label. Explicitly calling out the direction with beq 1f and bne 2b in the macro resolves the ambiguity and generates the right jumps in both invocations of the macro.

If you choose to use something that isn't a true local label, then not only do you potentially clutter up your symbol table with junk, but you also rob yourself of being able to use loops or conditional branching in macros since you'd generate non-unique symbols. My example might seem a bit contrived, but switch from assembler macros to inline asm blocks in C functions which get inlined all over your complex codebase, and things get a lot more real .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM