The difference between pseudo instructions ADR and LDR

Publisher:泉趣人Latest update time:2016-04-01 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
ARM assembly has ldr instruction and ldr, adr pseudo-instructions, they can use label expressions as operands, the following will explain their differences by analyzing a piece of code and the corresponding disassembly results. ldr r0, _start 
adr r0,_start 
ldr r0, =_start 
_start: 
b _start
When compiling, RO is set to 0x30000000 (runaddress). The following is the result of disassembly: 0x00000000: e59f0004 ldr r0, [pc, #4] ; 0xc 0x00000004: e28f0000 add r0, pc, #0 ; 0x0 0x00000008: e59f0000 ldr r0, [pc, #0] ; 0x10 0x0000000c: eafffffe b 0xc 0x00000010: 3000000c andcc r0, r0, ip ------------------------------------------ 1.ldr r0, _start: Simply put, it reads out the value stored in the _start address. The assembler calculates the value #4 that needs to be added to the pc from the current position to _start (here is a label, a position expression relative to the program), and then adds the offset #4 to the current pc (actually the current address + 2 instruction bytes long) to get the memory address where _start is located, and then takes the value of the memory address and puts it in r0. As long as the relative position of this instruction and the label _start remains unchanged, the value of R0 is the same 0xeafffffe 2.adr r0, _start Simply put, it reads out the _start address, and this address is relative to the current pc, so it is related to the current program running address. If it runs at 0x30000000, r0 = pc(0x30000004 + 0x08) + #0 = 0x3000000C; if it runs at 0x00000000, r0 = pc(0x00000004 + 0x08) + #0 = 0x0000000C, so running at different locations, r0 gets different results, the only determined relative offset. The relocate code in U-boot uses adr to realize whether the current program is in RAM or flash. The following is a brief analysis. -------------------------------------------------------------------------------- relocate: // Relocate U-Boot to RAM // adr r0, _start // r0 is the current location of the code // // adr pseudo-instruction, the assembler automatically calculates the value of PC when executing to _start through the current PC value, and puts it in r0: when this segment is executed in flash, r0 = _start = 0; when this segment is executed in RAM, _start = _TEXT_BASE (the value specified in board/smdk2410/config.mk is 0x30000000, that is, the beginning of the code segment where u-boot copies the code to RAM for execution) // ldr r1, TEXT_BA_SE // Test to determine whether it is started from Flash or RAM // // The result of this sentence execution, r1 is always 0x30000000, because this value is specified by the compiler (set in ads, or -D sets the compiler parameter) // cmp r0, r1 // Compare r0 and r1, do not perform relocation during debugging// -------------------------------------------------------------------------------- 3. ldr, r0, =_start This is a pseudo instruction, which gets the absolute address of _start. No matter where it runs, r0 = 0x3000000C /// ... Here is a record of the usage of ADRL: Function: Load the address relative to the program or relative to the register into the register. Similar to the ADR instruction. ADRL generates two data processing instructions, so it has a wider address range than ADR. Syntax ADRL{cond} Rd, label Where: cond: is an optional conditional code. Rd: is the register to be loaded. label: is an expression relative to the program or register. The range given above is relative to a point that is located after the current instruction address and is four bytes (in Thumb code) or two words (in ARM code) away from the current instruction. If the alignment is 16 bytes, or the correlation with this point is higher, the range of the remote address can be larger. While checking ADRL, I saw a blog post about the difference between ldr and adr. I felt it was well written, so I excerpted it. http://coon.blogbus.com/logs/2738861.html ldr r0, _start adr r0, _start ldr r0, =_start nop mov pc, lr _start: nop Set RO to 0x0c008000 when compiling ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ 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: e1a00000 nop (mov r0, r0) c008018:0c008014 stceq 0, cr8, [r0], -#80 Analysis: ldr r0, _start reads the value from the memory address _start. After executing this, r0 = 0xe1a00000 adr r0, _start gets the address of _start to r0, but please look at the result of decompilation, it is independent of the position. In fact, it is obtained at a relative position. For example, if this code runs at 0x0c008000, then adr r0, _start gets r0 = 0x0c008014; if it runs at address 0, it is 0x00000014. ldr r0, =_start gets the absolute address of the label _start. This absolute address is determined during linking. It looks like this is just one instruction, but it takes up two 32-bit spaces, one for the instruction and the other for the data of _start (because the value of _start cannot be determined during compilation, and the mov instruction cannot be used to assign a 32-bit constant to r0, so an extra space is needed to store the real data of _start, which is 0x0c008014 here). Therefore, it can be seen that this is absolute addressing. No matter where this code is run, its result is r0 = 0x0c008014. The biggest gain from reading this article is not to understand the usage of these commands, but the key lies in the use of disassembly. With disassembly, you can see the specific differences between different usages. Note: Disassembly can be achieved using arm-linux_objdump.
Reference address:The difference between pseudo instructions ADR and LDR

Previous article:I2C Bus Driver
Next article:Write your own bootloader

Recommended ReadingLatest update time:2024-11-16 14:39

ARM assembly instructions ADR and LDR usage
Introduction Both of them are pseudo instructions: ADR is a pseudo instruction for reading addresses in a small range, and LDR is a pseudo instruction for reading addresses in a large range. The practical difference is: ADR is a pseudo instruction for reading an address value based on a PC relative offset or a registe
[Microcontroller]
The origin and development of LDR instructions and LDR pseudo-instructions in the ARM exception vector table
1. Problem elicitation In ARM development, the exception vector table (or interrupt vector table) is in a key position because it controls the jump address when the ARM chip is reset, that is, where to call to execute the startup code. Generally speaking, the form of the exception vector table is as follows   p Ve
[Microcontroller]
The origin and development of LDR instructions and LDR pseudo-instructions in the ARM exception vector table
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号