当前位置:网站首页>ARM assembly instruction ADR and LDR

ARM assembly instruction ADR and LDR

2022-08-11 06:34:00 Emily_rong_2021

Introduction

Both are pseudo-instructions: ADR is a small-range address read pseudo-instruction, and LDR is a large-range address read pseudo-instruction.The practical differences are: ADR is a pseudo-instruction that reads an address value based on a PC-relative offset or a register-relative address value, while LDR is used to load a 32-bit immediate value or an address into a specified register.

adr r0, _start gets the current execution position of _start, and the effective address is determined by pc+offset
ldr r0, =_start gets the absolute address, which is determined when linking;
------------------------------------------------------------------------
/* Relocate Boot code to RAM memory, move Boot code from FLASH to RAM */
relocate: /* relocate U-Boot to RAM */
adr r0, _start /* r0 <- current position of code */
/****************************************************************************
* Move the relative address of _start to r0, the relative addressing takes the current value of the program counter PC as the base address,
* The address label in the instruction is used as the offset, and the twoAfter the addition, the effective address of the operand is obtained.
* It is independent of position, mainly depends on where Boot is running, that is, where the PC pointer is (assuming the _start offset is 0),
* For example, this code is at 0x02000000 (FLASH start address) to run, that is, PC=0x02000000 at this time, then adr r0, _start gets r0 = 0x02000000;
* If it runs at address 0x81008000 (Boot loads the address in RAM), that is, PC=0x81008000 at this time, then r0 is 0x81008000.
*
* Pay attention to the difference between ldr and adr, see the following code snippet:
* ldr r0, _start
* adr r0, _start
* ldr r0, =_start
* nop
* mov pc, lr
* _start:
* nop
* Here is the disassembly result:
* 0c008000 <_start-0x14>:
* c008000: e59f000c ldr r0, [pc, #12] ; c008014 <_start>
* c008004: e28f0008 add r0, pc, #8 ; 0x8
* c008008: e59f0008 ldr r0, [pc, #8] ; c008018<_start+0x4>
* c00800c: e1a00000 nop (mov r0,r0)
* c008010: e1a0f00e mov pc, lr
*
* 0c008014 <_start>:
* c008014: e1a00000nop (mov r0,r0)
*
* Analysis:
* ldr r0, _start
* Read the value from the memory address _start.After executing this, r0 = 0xe1a00000
*
* adr r0, _start
* takes the address of _start to r0, but look at the decompiled result, it is position independent.In fact, it is a relative position.For example, this code runs at 0x0c008000,
* then adr r0, _start gets r0 = 0x0c008014; if it runs at address 0, it is 0x00000014.That is, the current PC value plus the offset of _start.
*
* ldr r0, =_start
* This gets the absolute address of the label _start.This absolute address is determined at link time.It seems that this is just an instruction, but it takes up 2 32bit spaces,
* one is the instruction and the other is the data of _start (because the value of _start cannot be determined at compile time, so you cannot use mov directlyThe instruction to assign a 32bit constant to r0,
* Therefore, an extra space is needed to store the real data of _start, which is determined at the time of link, here is 0x0c008014).
* So it can be seen that this is absolute addressing, no matter where this code runs, its result is r0 = 0x0c008014

(5 messages) adr instructionclass=link-link>icon-default.png?t=LBL2https://blog.csdn.net/u010886535/article/details/52800184

原网站

版权声明
本文为[Emily_rong_2021]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/223/202208110515131559.html