Signed integer-to-ascii x86_64 assembler macro
The trick to not counting -0x80000000 as a negative number is to use unsigned division.  IDIV is signed, DIV is unsigned.
One option to consider: If you fill the buffer from the end and output the pointer to the start of the data, then you don't need to relocate things.  Admittedly, this makes it harder to use in some cases.
You might be better using DI (instead of R12) to hold your output address, and STOSB to store a character there.  It not only writes the character, but increments DI.