Chan Kim
Chan Kim

Reputation: 5989

can't understand armv7 adr_l instruction example

This is an example code in https://developer.arm.com/documentation/dui0068/b/arm-instruction-reference/arm-pseudo-instructions/adrl-arm-pseudo-instruction

start   MOV     r0,#10
        ADRL    r4,start + 60000     ; => ADD r4,pc,#0xe800
                                     ;    ADD r4,r4,#0x254

I can't understand the comment in the code. Since 60000 is 0xea60. I think r4 should be pc + #0xea60. But the comment says (actually, emitted instruction) r4 becomes pc + #0xe800 + #0x254 = pc + 0xea54. (not #ea60). Why 12 less?

Upvotes: 0

Views: 290

Answers (1)

Nate Eldredge
Nate Eldredge

Reputation: 58518

These are arm (i.e. arm32) instructions, even though your title and tag originally said arm64. Note that the registers are r0, etc, instead of x0 or w0.

On 32-bit ARM in non-Thumb (A32) state, the PC reads as the address of the current instruction plus 8. (This is explained in the Architecture Reference Manual, E.1.2.3 in my copy of the Armv8-A version.)

So if start is at address 0x0, the ADD r4,pc,#0xe800 instruction is at address 0x4, and so pc will be read as 0xc. Thus ADD r4,pc,#0xe800 will load r4 with 0xe80c. Then adding 0x254 will leave r4 containing 0xea60 as desired.

arm64 is different. There, the PC is not accessible as a general-purpose register, so you can't move to and from it directly, but instructions like ADR that act on it do treat it as pointing to the current instruction (without the 8 byte offset).

Upvotes: 4

Related Questions