10

The documentation for LDP and STP gives an example instruction with an exclamation mark in the end:

LDP X8, X2, [X0, #0x10]!

Also the documentation about porting A32 PUSH/POP instructions into A64 gives the following examples:

PUSH {r0-r1} ---> STP X0, X1, [SP, #-16]!
POP {r0-r1}  ---> LDP X0, X1, [SP], #16

Neither of the pages explains what the exclamation mark in the end of the instructions means. What does it?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Serge Rogatch
  • 13,865
  • 7
  • 86
  • 158
  • 2
    Have you considered reading the documentation on addressing modes (the ! denotes that not only is the offset added to `sp` but also is the result written back to `sp` if I recall correctly). – fuz Sep 29 '16 at 21:32
  • 4
    It means exactly the same thing it has meant in ARM pre-indexed addressing modes for the last 3 decades, and that every instruction set reference covers, _including_ the appropriate section of the very document you linked... (hint: 6.3.4) – Notlikethat Sep 29 '16 at 21:32
  • 8
    @Notlikethat not everyone has been in this game for 3 decades. Why the shade? Something like this is not easy to search for in the arm architecture documentation. – 0-0 Sep 11 '18 at 23:54

1 Answers1

16

The ! means "Register write-back": the base register is used to calculate the address of the transfer, and is updated.

In your example:

LDP X8, X2, [X0, #0x10]!

X0 modified so that after the operation:

X0 = X0 + 0x10

If you do not put the !, X0 is not modified by the operation.

On the second example concerning PUSH/POP, the difference is when the increment is done:

STP X0, X1, [SP, #-16]! stores at address SP-16, and SP is decremented in the same way

LDP X0, X1, [SP], #16 loads from address SP, and after the transfer is performed, stores SP+16 to SP.

Dric512
  • 3,525
  • 1
  • 20
  • 27
  • 2
    This documentation says a different thing: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0024a/ch05s01s03.html . With `!` the target register is incremented before the operation, without `!` - after. – Serge Rogatch Sep 30 '16 at 06:32
  • The link does not seem correct. But anyway I think you are comparing the 2 write-back forms: `LDR x1, [x0, #imm]!` or `LDR x1, [x0], #imm`. The first form loads at `x0+#imm` (Increment before), the second loads at `x0`. – Dric512 Oct 01 '16 at 19:16
  • This link should be correct: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0024a/CJAIFJII.html – Serge Rogatch Oct 02 '16 at 04:12
  • Thanks. This is similar to what I described: `LDR x1, [x0, #imm]!` does the access at `x0+#imm`, and updates the register to this value. The fact that the register is updated before or after is just a way of describing it. – Dric512 Oct 03 '16 at 05:49
  • 1
    "If you do not put the !, X0 is not modified by the operation.", "LDP X0, X1, [SP], #16 loads from address SP, and after the transfer is performed, stores SP+16 to SP." - don't these contradict? As I understand, the register is always updated, just `!` indicates whether before or after. – Serge Rogatch Oct 03 '16 at 17:16
  • 5
    The `!` only has a meaning for the form like: `LDR X0, [XP, #16]`, which is called pre-increment. Depending on `!`, the base register is updated or not. For the other form, called post-increment: `LDR X0, [SP], #16`, write-back always occurs (ie base is updated), and `!` is not permitted. – Dric512 Oct 03 '16 at 21:09