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, 2014 at 18:00
  • 2
    @JamalS: there's no Intel syntax for ARM
    – Igor Skochinsky
    Aug 12, 2014 at 20:49
  • @JamalS: You should have noticed that register list is not something common in x86 operands. :-)
    – perror
    Aug 12, 2014 at 21:46
  • @perror: Yes, I forgot x86 starts at r8 instead of r0 :)
    – JamalS
    Aug 13, 2014 at 6:59

1 Answer 1


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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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