I am quite new to ARM assembly, I already saw that the bang (!) is used to really update a register after a computation in the addressing mode syntax, but I can't figure out what is the difference of semantics between (this output is from objdump so it uses gas syntax):

ldm r4!, {r0, r1, r2, r3}


ldm r4, {r0, r1, r2, r3}

Any idea ?

  • By the way, you can use Intel syntax with objdump, just specify objdump -M intel – JamalS Aug 12 '14 at 18:00
  • 2
    @JamalS: there's no Intel syntax for ARM – Igor Skochinsky Aug 12 '14 at 20:49
  • @JamalS: You should have noticed that register list is not something common in x86 operands. :-) – perror Aug 12 '14 at 21:46
  • @perror: Yes, I forgot x86 starts at r8 instead of r0 :) – JamalS Aug 13 '14 at 6:59

The ! denotes writeback of the base register. Base register is the register used to address the memory to be read or written - in your case it's R4. Writeback means that the base register will be updated with the delta equal to the size of transferred data.

So, the instruction

ldm r4!, {r0, r1, r2, r3}

can be represented by the following pseudocode:

r0 = *(int)(r4) 
r1 = *(int)(r4+4) 
r2 = *(int)(r4+8) 
r3 = *(int)(r4+12) 
r4 = r4 + 16 // writeback (16 bytes transferred)

In the variant without ! the writeback doesn't happen so R4 retains the original value.

In the LDR and STR instructions you may also encounter pre-indexed and post-indexed notation:

LDR R0, [R4, #4]  ; simple offset: R0 = *(int*)(R4+4); R4 unchanged
LDR R0, [R4, #4]! ; pre-indexed:   R0 = *(int*)(R4+4); R4 = R4+4
LDR R0, [R4], #4  ; post-indexed:  R0 = *(int*)(R4+0); R4 = R4+4

For more information see the ARM Assembler Guide.

| improve this answer | |

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.