I use the following in 64-bit mode:
; -----------------------------------------------------------------------------
; os_int_to_string -- Convert a binary interger into an string
; IN: RAX = binary integer
; RDI = location to store string
; OUT: RDI = points to end of string
; All other registers preserved
; Min return value is 0 and max return value is 18446744073709551615 so your
; string needs to be able to store at least 21 characters (20 for the digits
; and 1 for the string terminator).
; Adapted from
http://www.cs.usfca.edu/~cruse/cs210s09/rax2uint.sos_int_to_string:
push rdx
push rcx
push rbx
push rax
mov rbx, 10 ; base of the decimal system
xor ecx, ecx ; number of digits generated
os_int_to_string_next_divide:
xor edx, edx ; RAX extended to (RDX,RAX)
div rbx ; divide by the number-base
push rdx ; save remainder on the stack
inc rcx ; and count this remainder
cmp rax, 0 ; was the quotient zero?
jne os_int_to_string_next_divide ; no, do another division
os_int_to_string_next_digit:
pop rax ; else pop recent remainder
add al, '0' ; and convert to a numeral
stosb ; store to memory-buffer
loop os_int_to_string_next_digit ; again for other remainders
xor al, al
stosb ; Store the null terminator at the end of the string
pop rax
pop rbx
pop rcx
pop rdx
ret
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
; os_string_to_int -- Convert a string into a binary interger
; IN: RSI = location of string
; OUT: RAX = integer value
; All other registers preserved
; Adapted from
http://www.cs.usfca.edu/~cruse/cs210s09/uint2rax.sos_string_to_int:
push rsi
push rdx
push rcx
push rbx
xor eax, eax ; initialize accumulator
mov rbx, 10 ; decimal-system's radix
os_string_to_int_next_digit:
mov cl, [rsi] ; fetch next character
cmp cl, '0' ; char preceeds '0'?
jb os_string_to_int_invalid ; yes, not a numeral
cmp cl, '9' ; char follows '9'?
ja os_string_to_int_invalid ; yes, not a numeral
mul rbx ; ten times prior sum
and rcx, 0x0F ; convert char to int
add rax, rcx ; add to prior total
inc rsi ; advance source index
jmp os_string_to_int_next_digit ; and check another char
os_string_to_int_invalid:
pop rbx
pop rcx
pop rdx
pop rsi
ret
; -----------------------------------------------------------------------------