The difference between LDR, MOV and ADR instructions in assembly

When looking at the first boot stage of BootLoader, careful students will find that the code uses mov r1, # 0x3; ldr r0, = INTMSK; adr r0, _start and other commands to get a value to the specified register, so why Want to use different instructions to get the value instead of directly using the MOV instruction? Before explaining, first briefly introduce the functions of these commands.

  • MOV is a data transfer instruction format: MOV {<cond>} {s} <Rd>, <shifter_operand>, the role is to transfer the data represented by <shift_operand> to the target register <Rd>
  • LDR pseudo-instruction, format: LDR R0, = XXX. The role is to transfer the value to the R0 target register.
  • The purpose of the ADR R0, _start directive is to transfer the value of _start to the target register R0.
    That is, these three instructions are to get the value and transfer it to the target register, but the latter two are pseudo-instructions, not real assembly language. When the compiler sees it, it will be converted into real assembly language.
    The operation data following the MOV instruction can be registers, immediate data (not all numbers are immediate data).
    The number following the LDR instruction can be arbitrary, and it may not be immediate.
    The ADR instruction transfers the address of _start to R0, which is converted into a true assembly instruction similar to: SUB R0, PC, # 172. It is addressed relative to the PC offset, that is, the instruction can be found through the PC instruction, within a small range before and after the PC. This generates position-independent code, which means that no matter where the program moves, the instruction address of _start can be correctly obtained. And if written as MOV R0, _start then the value in r0 will change with the program connection address. This instruction is used in code relocation. When power is turned on, the boot code is at the physical address 0. The code needs to be moved to the physical location specified by the linker.

The ADR instruction is mainly used to generate address-independent code, and it is not necessary to judge whether a number is an immediate number; the role of the LDR pseudo-instruction is that the subsequent data may not be an immediate number; while the MOV instruction is followed by a value, it can only be an immediate number. Can also be connected to other forms of operands.

Published 35 original articles · Like1 · Visits 1870

Guess you like

Origin blog.csdn.net/lzj_linux188/article/details/103645814