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
Reference address:The difference between pseudo instructions ADR and LDR
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.
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]
- Popular Resources
- Popular amplifiers
Recommended Content
Latest Microcontroller Articles
He Limin Column
Microcontroller and Embedded Systems Bible
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
MoreSelected Circuit Diagrams
MorePopular Articles
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
MoreDaily News
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
Guess you like
- Application of RPA in the customer service industry
- Efficiency Programming of Single Chip Microcomputer Active Buzzer Driver
- Today at 10:00 AM, live broadcast with prizes: ams projection lighting (MLA) enhances communication between cars and roads
- MSP430F5529 clock multiplier setting is effective
- MSP430F5538A watchdog
- [Qinheng Trial] 1. CH549EVT Product Display
- What are the necessary instructions for SIM800C transparent transmission mode?
- The relationship between computer vision and image processing, pattern recognition, and machine learning
- Effect of temperature on resettable fuse and its symbol
- Relay