Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting an label address to a register on ARM?

Tags:

assembly

arm

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

like image 943
superbriggs Avatar asked Apr 02 '13 21:04

superbriggs


People also ask

What is a label in ARM assembly?

A labellabelIn programming languages, a label is a sequence of characters that identifies a location within source code. In most languages, labels take the form of an identifier, often followed by a punctuation character (e.g., a colon).https://en.wikipedia.org › wiki › Label_(computer_science)Label (computer science) - Wikipedia is a symbol that represents the memory address of an instruction or data. The address can be PC-relative, register-relative, or absolute. Labels are local to the source file unless you make them global using the EXPORT directive. The address given by a label is calculated during assembly.

How are labels used in assembly?

A labellabelIn programming languages, a label is a sequence of characters that identifies a location within source code. In most languages, labels take the form of an identifier, often followed by a punctuation character (e.g., a colon).https://en.wikipedia.org › wiki › Label_(computer_science)Label (computer science) - Wikipedia can be placed at the beginning of a statement. During assembly, the label is assigned the current value of the active location counter and serves as an instruction operand. There are two types of lables: symbolic and numeric.

What is the difference between ADR and LDR?

LDR obtains the immediate data by putting the data in the program code and uses a PC relative load to get the data into the register. ADR tries to generate the immediate value by adding or subtracting instructions (for example, based on the current PC value).


1 Answers

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 - pc-relative
  2. adrl r0,target - pc-relative
  3. ldr r0,=target - absolute
  4. sub r0,pc,#(.+8-target) - learning only...

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 (4) is to manually calculated it. This is what the adr and adrl versions will windup translating to. It is not recommended, but is just to show how the . operator (current address), the pc and the label along with the convention that the ARM PC is eight ahead of the current executing instruction combine. If it looks confusing, this is why we have adr.

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 3rdldr 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, which is absolute addressing. 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

like image 103
artless noise Avatar answered Sep 20 '22 10:09

artless noise