Ask:
(1) LDR R1, = 0x12345678; loading 32-bit immediate count
LDR R1, 0x12345678
What are the differences?
Generally, when does LDR R1, = 0x12345678?
Under what circumstances does LDR R1, 0x12345678?
(2) LDR r0, = led_tab; load the label address
LDR r0, led_tab
What are the differences?
Generally, when is LDR r0, = led_tab used?
Under what circumstances should LDR R0 and led_tab be used?
========================================================== ================
A:
1. There is no "LDR R1, 0x12345678 ".
2. The following two commands are the same and are called "pseudo commands". That is to say, the compiler will replace this command with other appropriate commands.
LDR R1, = 0x12345678
LDR r0, = led_tab
If these values are not complex, they are replaced by mov commands, for example:
LDR R1, = 0x00
It will become:
MoV R1, #0x00
If these values are complex, the value will be stored somewhere during compilation and then read using the Read Memory command, for example:
LDR R1, = 0x12345678
Changed:
LDR R1, [PC, XXXXX] // This XXX is added to the PC, which is the address of some_locate. the compiler will help you do everything.
Some_locate:. Word 0x12345678
3. You said "LDR r0, = led_tab; load the label address", that's right,
Led_tab is an address label, which is a numerical value. When the compiler connects to the program, it determines its value. If it is very simple, it will use the mov command to assign values. If it is very complex, an address exists and is read using the Read Memory command.
4. LDR r0, led_tab
No "=" indicates "Read Memory ".
For example:
LDR r0, led_tab
LDR R1, = led_tab
Led_tab:. Work 0x12345678
The R0 value is 0x12345678, And the R1 value is the led_tab value, that is, the address where 0x12345678 is stored in the memory.
ADR refers to instructions for reading PC-based relative offset address values or register-based relative address values, and LDR is used to load 32 as the immediate number or an address to the specified register. Here we will see the difference. If you want to load a function in a program or specify an address during connection, use ADR, for example, the address to be located in the LDS. Use LDR when loading the 32-bit immediate number or external address.
Below is
LDR r0, _ start
LDR R1, _ text_base
LDR R2, _ armboot_start
LDR R3, _ bss_start
Sub R2, R3, r2
Add R2, R2, R0
And
ADR r0, _ start
LDR R1, _ text_base
ADR R2, _ armboot_start
ADR R3, _ bss_start
Sub R2, R3, r2
Add R2, R2, R0
Disassembly code of two fragments
80000068: e51f0070 LDR r0, [PC, # ffffff90]; 80000000 <_ Start>
8000006c: e51f1054 LDR R1, [PC, # ffffffac]; 80000020 <_ text_base>
80000070: e51f2054 LDR R2, [PC, # ffffffac]; 80000024 <_ armboot_start>
80000074: e51f3054 LDR R3, [PC, # ffffac]; 80000028 <_ bss_start>
80000078: e0432002 sub R2, R3, r2
8000007c: e0822000 add R2, R2, R0
--------------------------------------------------------------------------
80000068: e24f0070 sub r0, PC, #112; 0x70
8000006c: e24f1054 sub R1, PC, #84; 0x54
80000070: e24f2054 sub R2, PC, #84; 0x54
80000074: e24f3054 sub R3, PC, #84; 0x54
80000078: e0432002 sub R2, R3, r2
8000007c: e0822000 add R2, R2, R0
Because LDR is read 32 as the address, it will be automatically filled with fffff, but I don't know where to reduce it when using PC subtraction.