Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does an equals sign = on the right side of a LDR instruction in ARM mean?

Tags:

assembly

arm

ida

Been googling this for a while but i can't find any documentation relating to this. I've been trying to learn ARM and have been looking at the compiled ARM assembly code for a simple calculator.c program i wrote in order to see if I could understand what was going on. The thing I keep seeing is instructions like these:

LDR     R3, =__stack_chk_guard__GLIBC_2.4

or

LDR     R0, =aEnterOperator ; "Enter operator: "

or

LDR     R0, =aSIsNotAValidOp ; "%s is not a valid operator.  Enter +, -"

Note: the stuff after the semicolons is just the auto-comments added by IDA.

My question is, what does the '=' on the right side of these LDRs mean? In the first case, it seems to be some tag indicating the loading of a library; in the second and third cases, '=a' seems to be prefacing a printf. I'm just not quite sure to make of this, since I can't find anything about this syntax for LDR in the documentation. Can someone help me understand this? Thank you!

like image 801
Terry Martin Avatar asked Jun 15 '16 16:06

Terry Martin


People also ask

What is LDR instruction in arm?

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 the hashtag mean in assembly?

1. 2. In general in arm assembler the # is used to indicate an immediate value.

What does this instruction LDR R0 R1 do?

Generally, LDR is used to load something from memory into a register, and STR is used to store something from a register to a memory address. LDR R2, [R0] @ [R0] - origin address is the value found in R0. STR R2, [R1] @ [R1] - destination address is the value found in R1.

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.


2 Answers

The use of an equals sign (=) at the start of the second operand of the LDR instruction indicates the use of the LDR pseudo-instruction. This pseuo-instruction is used to load an arbitrary 32-bit constant value into a register with a single instruction despite the fact that the ARM instruction set only supports immediate values in a much smaller range.

If the value after the = is known by the assembler and fits in with the allowed range of an immediate value for the MOV or MVN instruction then a MOV or MVN instruction is generated. Otherwise the constant value is put into the literal pool, and a PC-relative LDR instruction is used to load the value into the register.

If Ida is generating these LDR= instructions when dissassembling code then it must have detected that the assembler or compiler chose the second option when generating the code you're looking at. The actual instruction is something like LDR R0, loc_1234567 (or more accurately something like LDR R0, [PC, #-1234]) and Ida is looking up the value in the literal pool at loc_1234567 for you.

like image 50
Ross Ridge Avatar answered Oct 11 '22 13:10

Ross Ridge


= is usually suffixed by an immediate constant and instructs the assembler to put the constant into a nearby literal pool and generate a pc relative memory operand to load it. This is useful since the ARM instruction format doesn't have enough space to store a full 32 bit constant. Loading constants that cannot be encoded in 8 bits (I think) plus a shift from a nearby literal pool is an effective and efficient way to circumvent this problem.

like image 4
fuz Avatar answered Oct 11 '22 13:10

fuz