What is this instruction trying to do?

 .text:4044A5EC LDR     R5, =(unk_40885080 - 0x4044A5F8)

Looking at the value of unk_40885080 it holds a value of 20 in the .data segment.


This seems to be ARM PIC (Position-Independent) code, where the address is given relative to the program counter. Ida detects this and shows the "real" address.

Unfortunately, you didn't post any code around the your single statement, so i'm using one of my own disassemblies to show you:

.text:00062454                 LDR             R3, [R4,#8]
.text:00062458                 MOV             R0, #0x2C ; ','
.text:0006245C                 LDR             R1, =(unk_218172 - 0x62474)  <--- a
.text:00062460                 MOV             R5, #0
.text:00062464                 MOV             R2, #4  ; n
.text:00062468                 STRB            R0, [R3,#0x12]
.text:0006246C                 ADD             R1, PC, R1                   <--- b
.text:00062470                 LDR             R3, [R4,#8]
.text:00062474                 ADD             R0, R3, #0x30 ; dest
.text:00062478                 STR             R1, [R3,#8]
.text:0006247C                 STR             R1, [R3,#0x14]

The code loads some value into R1 (a), then (b) adds PC to it. So, the value of the register is supposed to be a pointer into memory, but beause PC gets added later, the value that is loaded at 2645C wouldn't make any sense. Ida detects the ADD instruction, and shows the LDR instruction in a way that lets you see where it's supposed to point to.

The fact that the "correcting offset" of 0x62474 is not the address of the ADD instruction is because of pipelining within the processor; at the moment the ADD gets executed, the next instructions have already been read, so PC is two instructions "behind" where the ADD instruction is located.

(The reason why the compiler produces this kind of code is, when the same code gets loaded at a different address later it stays valid, even without the relocation patching the linker/loader would have to do otherwise. That's called PIC, or Position-independent code.)

| improve this answer | |
  • I think I follow, so what the psuedo code be for your example? – allbabel May 28 '14 at 19:43
  • You can't really make meaningful pseudo code from my example, because it's just a few instructions from a larger function. But if you really want pseudocode, then the combined instructions LDR R1, =(unk_218172 - 0x62474) and ADD R1, PC, R1 could be written in C as r1=&unk_218172 - the result is a pointer that points to that memory location, but these instructions don't access the memory itself; a following instruction that has [R1] in its operand would access the memory through the pointer. – Guntram Blohm May 28 '14 at 22:29
  • It isn't related to code, rather its an implementation of the compiler toolchain to support the concept of position independent code due to the architecture its running on. You could however do this with compiler flags like -pie (gcc) which should generate the necessary asm code. – gandolf May 28 '14 at 22:30
  • @gandolf: -fPIC, not -pie. – Guntram Blohm May 28 '14 at 22:32
  • Thanks @GuntramBlohm I was writing from memory, which can't be trusted. – gandolf May 28 '14 at 22:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.