About the LDR pseudocommands compiled by arm

Source: Internet
Author: User
We know that the arm cpu has a widely used command LDR, which is mainly used to load data from memory (or address space) to General registers. However, both armasm and GNU arm as provide a pseudo-command LDR with the same name. In practice, this pseudo-command is used in many cases. What are their differences? Next I will talk about my understanding.

Since I use the GNU tool chain, the following content is subject to the arm Syntax of GNU.

The syntax format of the LDR directive is as follows:
LDR <Reg>, = <constant-expression>

This constant expression <constant-expression> can contain a label (in arm assembly, the label is interpreted as a constant at the time of connection) without the # symbol before the constant.

Sample demo. S:

. Equ stack_base, 0x0c002000
. Equ stack_size, 0x00001000

. Text

LDR sp, = stack_base
Ldr sl, = stack_base-stack_size
Ldr pc, = entry


This is a legal assembly file. It sets the stack base address to 0x0c002000 and the stack limit to 0x0c001000, and then jumps to the C program identified by the entry for execution.

Assume that the address of the symbol "entry" is 0x0c000000.

If we write the above Code as follows:

. Text

MoV sp,
#0x0c002000

MoV SL,
#0x0c001000

MoV PC,
#0x0c000000


The assembler reports an error:
Demo. S: assembler messages:
Demo. S: 2: Error: Invalid constant -- 'mov sp, #0x0c002000'
Demo. S: 3: Error: Invalid constant -- 'mov SL, #0x0c001000'

The reason for this error is long enough. In short, it is because there is an important concept in the process that all commands are long. In the arm instruction set, all commands are 4 bytes long (the thumb instruction is 2 bytes ). The problem is that 4 bytes cannot store the command control code and 32-bit immediate number at the same time, so I want to set a 32-bit immediate number (such as a 32-bit address value) what should I do if I transfer it to a register?

A general method provided by the CPU is to read the address value as data rather than code from the corresponding location in the memory to the register. We will see this example later.

In addition, arm provides another solution. Since the instruction control code (Cond, opcode, S, RD, RN) of a transfer-type instruction occupies 20 bytes, only 12 digits can be provided immediately.

Arm does not use these 12 digits to directly store a 12-digit immediate number, but uses the same concept as valid numbers, only the valid bits of 8 bytes and the offset of a 4-bit (the Offset Unit is 2 ). This term is called immed_8 in arm. If you are interested, please contact us for more information.

It can be seen that the arm method can directly use a very limited number of immediate operations, such as 0xfffffff0 is obviously not supported. Don't worry. There is also an MVN instruction in arm's transmission class to solve this problem. Obviously, 0x0000000f is a valid immediate number, and MVN will first reverse it and then transmit it, so that the range of valid immediate number is doubled.

Even so, there are still a large number of 32-bit immediate numbers, such as 0x0c002000 and 0x0c001000 in the above example. To solve this problem, we need to use the general method of the RISC, and the second is to load data in batches.

For example, you can load 0x0c002000 as follows:

. Text
MoV sp, #0x0c000000
Add SP, SP, #0x00002000

Or:

. Text
MoV sp, #0x0c000000
Orr
SP, SP,
#0x00002000

It's tricky, right. But pay attention to the major difference between it and Method 1: Multiple commands are required. In some cases where the number of commands is limited, you cannot use it. For example, if you want to perform a long jump to the abnormal table (more than ± 32 MB), you can only use method 1; in addition, this operation is not atomic in the synchronization transaction, so it may need to be locked.

After pulling so much, return to the LDR pseudo command. Obviously, the above content is complex and cumbersome. For example, when writing a program, the programmer must consider whether a certain number is immed_8, which is a super troublesome issue. Therefore, LDR pseudo commands are introduced to reduce the burden on the programmer.

You must be curious about what the first demo. S was changed to by GNU as. Well, let's execute the following command in Linux:
Arm-elf-as-O demo. O demo. s
Arm-elf-objdump-D demo. o

Result:

Demo. O: File Format elf32-littlearm

Disassembly of section. Text:

00000000 <. Text>:
0: e59fd004 LDR sp, [PC, #4]; C <. Text + 0xc>
4: e59fa004 ldr sl, [PC, #4]; 10 <. Text + 0x10>
8: e59ff004 ldr pc, [PC, #4]; 14 <. Text + 0x14>
C: 0c002000 stceq 0, CR2, [R0]
10: 0c001000 stceq 0, CR1, [R0]
14: 00000000 andeq r0, R0, R0
Disassembly of section. Data:

Since the entry has not been connected to the target address, the objdump disassembly will regard it as 0. We will ignore it first. The other two LDR pseudo commands become the actual LDR commands! However, the objective is very strange: [PC, #4]. Let's take a look at [PC, #4.

We know that the PC stores the location of the next command of the current command, that is,. + 8. Then the first command LDR
SP, the PC in [PC, #4] is 0x8, PC + 4 is 0xc, and the content in [0xc] Is 0x0c002000. Likewise, the second LDR command is the same. Obviously, the LDR directive adopts the general-purpose method of Proteus.

In addition, if LDR is an immed_8 or immed_8 anticode number, it will be directly interpreted as mov or MVN commands. For example, ldr pc, = 0x0c000000 will be interpreted as mov PC, 0x0c000000.

In addition, I found that arm-elf-GCC usually uses the accumulate method. For example, in the C statement, I = 0x100ffc04; will become a statement similar to the following:
MoV r0, #0x10000004
Add r0, R0, #0x000ff000
Add r0, R0, #0x00000c00
...
The reason is unknown.

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.