SoFunction
Updated on 2025-03-04

Detailed explanation of assembly language LDR instructions and LDR pseudo-instructions

Detailed explanation of LDR instructions and LDR pseudo-instructions

The composition of ARM32-bit instructions

ARM is a RISC structure, and the data movement from memory to CPU can only be completed through LDR/STR instructions. 32bit = instruction code + data. Therefore, it is impossible for a 32bit instruction to represent another 32bit data. In fact, only 12bits are used to represent the immediate number, where 4bits represent the number of bits shifted (cycle right shift, and the value x2), and 8bits are used to represent a cardinality to be shifted. This creates the problem of illegal immediate numbers and legal immediate numbers. After the shift operation, the number that is not zero cannot be represented by 8 bits is illegal immediate numbers. The ldr pseudo-instruction is used to solve the problem of illegal immediate counting.

The difference between the use of ldr directive and ldr directive:

ldr r0, =0xFFF0 @Pseudo-instruction
ldr r0, 0xFFFF @ command
The intuitive difference is that when the ldr pseudo-instruction is used, there will be "=" before the subsequent data. When actually using it, most pseudo-instructions are used, so there is no need to consider the issue of legal and illegal immediate counting. When compiling, the compiler will replace the ldr directive and use a literal pool to solve the problem of illegal immediate numbers. A text pool is to divide a piece of address space to store constants or addresses. When needed, data is retrieved by base address + index address, so that it does not need to be restricted by legal immediate numbers, and can represent 32 bit data. For example:
Assembly source code:
_start:
ldr r0, =0x11111111
Disassembled:
00000000 <_start>:
0: e59f009c ldr r0, [pc, #156] ; a4 <delay_loop+0x10>
·
·
·
98: e1520003 cmp r2, r3
9c: 1afffffc bne 94 <delay_loop>
a0: e1a0f00e mov pc, lr
a4: 11111111 tstne r1, r1, lsl r1
analyze:
Through disassembly, we can see that the ldr pseudo instruction is replaced by a register base address index instruction. The pc is the base address and offset by 156 bytes (hexadecimal is 0x9c). The purpose of this instruction is to read the 4 bytes starting with the memory address "pc + 156" into r0. At this time, the value of pc is equal to the address +8 of the current execution instruction (because of the pipeline), so pc + 156 = 0xa4, and the value stored at the 0xa4 address happens to be 0x1111111111. This completes loading 0x11111111 to r0.

Supplement 1:

There are pipelines in the RAM processor, and there are currently more than a dozen pipelines. However, in order to be compatible with ARM, no matter how many pipelines the Soc has, the value of the PC is equal to the current instruction address + 8. PC = current command address + 8, just remember.

Supplement 2:

Assembly language ldr pseudo-instructions

The pseudo-instructions are used to automatically split code values ​​and will split a statement into multiple statements.

Example:

/* Light up an LED light in the assembly */

.text
.global _start

_start:
    ldr r1, =0x56000050
    ldr r0, =0x100  /* Equivalent to mov r0, #0x100 */
    str r0, [r1]

    ldr r1, =0x56000054
    ldr r0, =0 /* mov r0, #0 */
    str r0, [r1]

halt:
    b halt

ldr r1, =0x56000054 is a pseudo instruction. Suppose we want to give the value of 56000054 to the r1 register, we can use mov r1, #56000050.
However, the length exceeds the length that the mov can receive, so it must be divided into high and low bytes to send, but at some point we still have to read the open document to know
Or if there is no development document, let the pseudo-instructions judge by themselves.

This is the end of this article about the detailed explanation of assembly language LDR instructions and LDR pseudo-instructions. For more related assembly language ldr pseudo-instructions, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!