Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

assembly - Getting an label address to a register on ARM?

How do I write an instruction which will have the address a label is referencing put into a register?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

There are four ways, three are documented at Sourceware's Gnu Assembler manual. I guess the label is something like,

 target:
     .long 0xfeadbeef
  1. adr r0,target
  2. adrl r0,target
  3. ldr r0,=target
  4. sub r0,pc,#(.+8-target)

The first two are very similar and generate sub r0,pc,#offset. The 3rd puts a long in a literal pool and loads this via ldr r0,[pc,#offset2] or it may use a mov if the assembler finds it can (usually an aligned label, like at 0x8000). The last version is to manually calculated it.

The difference between adr and adrl comes from immediate operands. They are 8bits rotated by a multiple of two. So if the address is far, you may need to perform two instructions, which will usually be faster than the 3rd ldr variant which get a full 32-bits via the data cache or memory.

See also: Relocation in assembler


Thumb2 adds the combination movw and movt. For example,

label:
 ; data
...
movw    r0, :lower16:label - .
movt    r0, :upper16:label - . 

This will put the offset in r0. It is not as useful for PC relative but useful for absolutes or direct loads of constants.

See: ARM blog on constants


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...