Understanding of ADR commands

Source: Internet
Author: User
Tags sub command

Let's take a look at the LDR command.

The LDR Command Format of the LDR command is LDR {condition} destination register. The <memory address> LDR command is used to transmit a 32-bit word base from the memory to the destination register. This command is usually used to read 32-bit word data from memory to General registers and then process the data. When the program counter PC is used as the destination register, the word data read from the memory by the instruction is used as the destination address, so as to redirect the program flow. This command is commonly used in programming and has various addressing methods. Please master it carefully. Command example: LDR r0, [R1]; read the word data with the memory address R1 into the register R0. LDR r0, [R1, R2]; read the word data with the memory address R1 + R2 into the register R0. LDR r0, [R1, #8]; read the word data with the memory address R1 + 8 into the register R0. LDR r0, [R1, R2]! Read the word data with the memory address R1 + R2 into the register r0, and write the new address R1 + R2. LDR r0, [R1, #8]! Read the word data with the memory address R1 + 8 into the register r0, and write the new address R1 + 8 into R1. LDR r0, [R1], R2; read the word data with the memory address R1 into the register r0, and write the new address R1 + R2. LDR r0, [R1, R2, LSL #2]! Read the word data with the memory address R1 + R2 × 4 into the registers r0, and write the new address R1 + R2 × 4 into R1. LDR r0, [R1], R2, LSL #2; read the word data with the memory address R1 into the register r0, and write the new address R1 + R2 × 4 to R1.

ADR: This command reads PC-based address values or register-based address values to registers. It performs address operations based on PC values.


Comparison between the LDR command and the ADR command:

LDR Reg, = {lab} OR = {num} is a pseudo command used to load the label address and the immediate number. If no "=" sign is added, it indicates memory addressing. ADR is a pseudo command that reads the address value based on the relative offset of the PC or the relative address value of the Register.


In fact, both are pseudo commands: ADR is a small range of address read pseudo commands, LDR is a large range of read address pseudo commands. In fact, ADR uses the address value based on the relative offset of the PC or the instruction based on the relative address value of the Register, 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.
An online example:
AREA test,CODE,READONLY        ENTRYSTART             ldr r0,_start        adr r0,_start        ldr r0,=_start        nop        _start        nop        END

This code has no practical significance, just for convenience. Let's take a look at the disassembly:
START    $a    test        0x00000000:    e59f0008    ....    LDR      r0,_start     ; [0x10] = 0xe1a00000        0x00000004:    e28f0004    ....    ADR      r0,{pc}+0xc ; 0x10        0x00000008:    e59f0004    ....    LDR      r0,[pc,#4]    ; [_start = 0x14] = 0        0x0000000c:    e1a00000    ....    MOV      r0,r0    _start        0x00000010:    e1a00000    ....    MOV      r0,r0    $d        0x00000014:    00000000    ....    DCD    0 ; _start
/***********************************

Axd simulation determines Ro segment address: 0x50200000

Decompilation
********************************/

LDR r0, _ start
Read the value from the memory address _ start. After executing this command, R0 = 0xe1a00000
ADR r0, _ start
Get the address of _ start to R0. However, please refer to the decompilation result. It is irrelevant to the location. In fact, the obtained location is relative. For example, if this code is run in 0x00000000, R0 = 0x00000010 is obtained for ADR R0 and _ start;
LDR r0, = _ start
Obtain the absolute address of _ start. This absolute address is determined during link. It seems that this is only an instruction, but it takes up two 32bit spaces. One is the instruction and the other is the data of _ start (because the value of _ start cannot be determined during compilation, in addition, the mov command cannot be used to assign a 32bit constant to R0. Therefore, an extra space is required to store the real data of _ start. Here it is 0x0000000c ).
Therefore, we can see that this is an absolute addressing. No matter where the code runs, the result is R0 = 0x0000000c.


Let's look at another piece of code:

        ldr     r0, _start        adr     r0, _start        ldr     r0, =_start_start:        b  _start

The following is the result of disassembly:

START    $a    $v0    test        0x00000000:    e59f0004    ....    LDR      r0,_start     ; [0xc] = 0xeafffffe        0x00000004:    e28f0000    ....    ADR      r0,{pc}+8 ; 0xc        0x00000008:    e59f0000    ....    LDR      r0,[pc,#0]    ; [_start = 0x10] = 0    _start        0x0000000c:    eafffffe    ....    B        {pc}  ; 0xc    $d        0x00000010:    00000000    ....    DCD    0 ; _start

Set Ro to 0x50200000 axd simulation decompilation:

1. LDR   R0, _ start
   This is an instruction that reads the value from the memory address _ start.
Here _ start is a label (a relative program expression). The assembler calculates the offset relative to the PC and generates the command relative to the pre-index of the PC: LDRR0, [0xc]. After the command is executed, R0 = 0 xeafffffe.

2. ADR   R0, _ start
   This is a pseudocommand, which is always compiled into an instruction by the assembler. The assembler attempts to generate a single add or sub command to load the address. If the address cannot be constructed in a command, an error is generated and the Assembly fails.
   Here we get the address number _ start to R0. Because the address is relative to the program, the ADR generates code dependent on the location. In this example, It is compiled into: addR0, PC, #0. Therefore, the code can be moved without changing the relative position of the label. After execution, R0 = 0x5020000c
   If this code is run in 0x50200000, the "R0" and "_ start" operations result in R0 = 0x5020000c. If the code is run in address 0, it is 0x0000000c.
   This can be used to determine where the program is running. The relocate code in U-boot is to use ADR to implement whether the current program is in Ram or flash. The following is a brief analysis.

3. LDR   R0, = _ start
   This is a pseudo command, a relative program or an external expression. The assembler places the value of label-expr of the relative program in a text pool and generates a LDR command for the relative program to load the value from the text pool, in this example, the command is LDR.R0, [PC, #0], corresponding address and value in the text pool: 0x50200010: 5020000c. If label-expr is an external expression or is not included in the current segment, the assembler places a link program relocation command in the target file. The link program generates an address when linking.
   Therefore, the absolute address of the label _ start is obtained, which is determined during connection. It occupies 2 32bit space, one is the instruction, and the other is the absolute address for storing _ start in the text pool. Therefore, no matter where the code runs in the future, the result is R0 = 0x5020000c. Because LDR R0 and = _ start obtain the absolute address of _ start, this code can be moved without changing the absolute position of the _ start label; if you use the register PC, you can implement absolute transfer in the program.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.