Look at the assembly these days, LDR and ADR between the differences are always confusing, see a lot of data more and more dizzy, so wrote a test program anti-compilation A moment all clear, see below:
Source:
ADR R0, _start
Nop
Ldr R0, _start
Nop
Ldr R0, =_start
Nop
_start:
Nop
MOV IP, LR
After disassembly:
8068:e28f0010 add R0, PC, #16
806c:e1a00000 NOP; (mov r0, r0)
8070:e59f0008 Ldr r0, [pc, #8]; 8080 <_start>
8074:e1a00000 NOP; (mov r0, r0)
8078:e59f0008 Ldr r0, [pc, #8]; 8088 <_start+0x8>
807c:e1a00000 NOP; (mov r0, r0)
00008080 <_start>:
8080:e1a00000 NOP; (mov r0, r0)
8084:E1A0C00E mov IP, LR
8088:00008080. Word 0x00008080
It's easy to understand the code after disassembly:
ADR r0, _start; relative fetch, the value of the pc+16 is saved in R0:8088, which is changed with different links; PS: This is the PC pointer;
Ldr R0,_start and Ldr R0,=_start; The former takes the value of the start label address 8080: e1a00000, which obtains the value of 8088 places where the start label is stored: 00008080;
Because ADR R0, _START;R0 exists in the pc+16 of the PC pointer address, so it will vary with the PC, it is called relative access;
The values of [pc+8] are present in Ldr R0,_start and Ldr r0,=_start;r0 and are not changed, so they are called absolute values.
The difference between LDR and ADR