0

In an iPhone project, I'm compiling a .s assembly file. In this file, I need to access the address of an external C variable and load it into a register. I have the code below:

_execute_read_spsr:
  ldr r0,=_spsr_pointer
  ldr r0, [r0]
  ldr r0, [r0]
  bx lr 

However, when compiling, Clang/LLVM throws an error on the first line of the method, saying:

unexpected token in operand
  ldr r1,=_spsr_pointer
         ^

I've read somewhere that the iOS assembler does not support this form of pseudo-operation. Unfortunately, this is code I've received from someone else, and my knowledge of assembly is limited. What would be the equivalent of this line of code that the assembler would accept?

Riley Testut
  • 431
  • 1
  • 8
  • 22
  • This is covered in [9.4.5 of the Gnu Assembler manual](http://sourceware.org/binutils/docs/as/ARM-Opcodes.html). The `ldr r1,[pc, #offset]` is the most generic. Why do you use this assembler? [Wordpress ARM Assembler for iOS](http://38leinad.wordpress.com/2011/04/06/arm-assembler-for-ios-part-1-environment-setup/) and [iOS ARM Assembler tutorial](http://www.shervinemami.info/armAssembly.html) all seem to say you can use `gas` or any assembler. Can the *iOS* linker not handle *elf*? – artless noise Jun 04 '13 at 16:56
  • Possible duplicates: [IPhone asm ldr](http://stackoverflow.com/questions/9735169/iphone-asm-ldr-params), [LLVM LDR syntax](http://stackoverflow.com/questions/9374703/llvm-gcc-assembler-ldr-syntax), [LDR vs MOV](http://stackoverflow.com/questions/14046686/ldr-vs-mov-arm-assembly), [Placing address in a register](http://stackoverflow.com/questions/15774581/placing-the-address-a-register-is-pointing-at-in-to-a-register). – artless noise Jun 04 '13 at 17:07

1 Answers1

1
ldr r1,=_spsr_pointer

Would be converted into either:

mov r1,#_spsr_pointer

or

ldr r1,[pc, #offset_to_spsr_ptr]
...
spsr_ptr: .word _spsr_pointer

Depending on the value of _spsr_pointer.

Michael
  • 57,169
  • 9
  • 80
  • 125
  • Thanks! The first one works. _spsr_pointer is a uint32* defined in a .cpp file. – Riley Testut Jun 04 '13 at 17:11
  • @RileyTestut That would be surprising. The `mov` form is limited to an *8-bit* value rotated `2*x`. There are a limited amount of constants it can represent. It is possible that your assembler inserts multiple instructions, like `mov` and `add`. I guess you don't care as long as it works. – artless noise Jun 04 '13 at 18:30
  • 1
    @artlessnoise: on ARMv6T2 and later it's possible to load any 16-bit immediate using `mov`. However, it's still unlikely that an address would fit, so it's possible that the assembler the OP is using is silently using only the least significant bits of the immediate. – Michael Jun 04 '13 at 19:07