1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
# --------------------------------------------
# FUNCTION: int2str
# PURPOSE : Convert a 64 bit integer into ASCII
# INPUTS : rdi = 64 bit integer
# rsi = address of buffer
# OUTPUTS : rax = address of string (points into the provided buffer)
# rdx = length of string
# CLOBBERS: rax, rcx, rdi, rsi, r8, r9, r10
# --------------------------------------------
.section .text
.globl int2str
.type int2str, @function
int2str:
pushq %rbx # save callee-saved register
movq %rdi, %rax # integer to convert
movq %rsi, %rbx # buffer base
movq %rsi, %r9 # save original buffer
leaq 19(%rbx), %r8 # pointer to last char position
movq $10, %rcx # divisor
xorq %r10, %r10 # sign flag (0 = positive)
# handle sign
testq %rax, %rax
jns .convert
negq %rax # if the number negative we negate it and
movq $1, %r10 # set sign flag
.convert:
testq %rax, %rax
jnz .loop # check if the number is 0
# if the number is 0, we just set the char to '0', and length to 0.
movb $'0', (%r8)
movq %r8, %rax
movq $1, %rdx
jmp .shift_left # shift the result leftmust
.loop:
xorq %rdx, %rdx # clear rdx before division
divq %rcx # divide rdx:rax by 10
addb $'0', %dl # add ASCII base
movb %dl, (%r8) # move digit into buffer
decq %r8 # decrement pointer
testq %rax, %rax # while quotient is not 0, loop
jnz .loop
incq %r8 # move back to first digit
# add '-' if negative
testq %r10, %r10
jns .calc_len
decq %r8
movb $'-', (%r8)
.calc_len: # count length of the string
movq %r8, %rax # string start
leaq 20(%r9), %rdx # end of buffer
subq %rax, %rdx # string length
.shift_left:
# shift string to leftmost in buffer if not already there
cmpq %rax, %r9
je .done # already leftmost
movq %rdx, %rcx # rcx = length of string
movq %rax, %rsi # rsi = source :: start of string
movq %r9, %rdi # rdi = destination :: original buff start
rep movsb # copy string left
# Found this online. It's a way to copy down values in memoery.
# movbs = Move String Byte..
# It copies 1 byte from memoery to memoery and
# incrementing destination and incrementing source.
# Source :: %rsi
# Dest :: %rdi
# rep = repeat wow.
# It's a prefix that repeats an isntructution rcx times
# https://stackoverflow.com/questions/27804852/assembly-rep-movs-mechanism
movq %r9, %rax # return pointer to start
.done:
popq %rbx
ret
|