Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use LDR over MOV (or vice versa) in ARM assembly?

I'm looking through this tutorial: http://www.cl.cam.ac.uk/freshers/raspberrypi/tutorials/os/ok01.html

The first line of assembly is:

ldr r0,=0x20200000 

the second is:

mov r1,#1 

I thought ldr was for loading values from memory into registers. But it seems the = means the 0x20200000 is a value not a memory address. Both lines seem to be loading the absolute values.

like image 838
Jonathan. Avatar asked Dec 26 '12 21:12

Jonathan.


People also ask

What is the difference between MOV and LDR in arm?

So mov is faster, but can only be used for 0-255. (Small numbers.) Ldr can move anything, but is slower.

Is LDR and MOV same?

LDR is used to move data from memory (usually RAM) into a CPU register. MOV is used to move data from one CPU register to another CPU register.

What does LDR do in assembly?

The LDR pseudo-instruction is used for two main purposes: to generate literal constants when an immediate value cannot be moved into a register because it is out of range of the MOV and MVN instructions. to load a program-relative or external address into a register.

What does LDR mean in ARM assembly?

LDR (immediate offset) Load with immediate offset, pre-indexed immediate offset, or post-indexed immediate offset.


1 Answers

It is a trick/shortcut. say for example

ldr r0,=main 

what would happen is the assembler would allocate a data word, near the instruction but outside the instruction path

ldr r0,main_addr ... b somewhere main_addr: .data main 

Now expand that trick to constants/immediates, esp those that cannot fit into a move immediate instruction:

top: add r1,r2,r3 ldr r0,=0x12345678 eor r1,r2,r3 eor r1,r2,r3 b top 

assemble then disassemble

00000000 <top>:    0:   e0821003    add r1, r2, r3    4:   e59f0008    ldr r0, [pc, #8]    ; 14 <top+0x14>    8:   e0221003    eor r1, r2, r3    c:   e0221003    eor r1, r2, r3   10:   eafffffa    b   0 <top>   14:   12345678    eorsne  r5, r4, #125829120  ; 0x7800000 

and you see the assembler has added the data word for you and changed the ldr into a pc relative for you.

now if you use an immediate that does fit in a mov instruction, then depending on the assembler perhaps, certainly with the gnu as I am using, it turned it into a mov for me

top: add r1,r2,r3 ldr r0,=0x12345678 ldr r5,=1 mov r6,#1 eor r1,r2,r3 eor r1,r2,r3 b top   00000000 <top>:    0:   e0821003    add r1, r2, r3    4:   e59f0010    ldr r0, [pc, #16]   ; 1c <top+0x1c>    8:   e3a05001    mov r5, #1    c:   e3a06001    mov r6, #1   10:   e0221003    eor r1, r2, r3   14:   e0221003    eor r1, r2, r3   18:   eafffff8    b   0 <top>   1c:   12345678    eorsne  r5, r4, #125829120  ; 0x7800000 

So it is basically a typing shortcut, understand that you are giving the assembler the power to find a place to stick the constant, which it usually does a good job, sometimes complains, not sure if I have seen it fail to do it safely. Sometimes you need a .ltorg or .pool in the code to encourage the assembler to find a place.

like image 84
old_timer Avatar answered Sep 22 '22 23:09

old_timer