-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprint_quad.s
128 lines (111 loc) · 2.23 KB
/
print_quad.s
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
.data
qstrpad: .ascii "00000000000000000000000000"
# longest possible number in 64 bits
qstr: .ascii "00000000000000000000"
qstrl: .quad 0
.text
.globl qstrpad
.globl qstr
.globl qstrl
.globl qprint_signed
.globl qprint_unsigned
.globl qstring_signed
.globl qstring_unsigned
qstr_rev:
leaq qstr(%rip), %r8
leaq qstrl(%rip), %rdx
movq (%rdx), %rdx
# rax is the left end index
# rdx is the right end index
xorq %rax, %rax
decq %rdx
qstrrevloop:
movb (%r8, %rax, 1), %dil
movb (%r8, %rdx, 1), %cl
movb %dil, (%r8, %rdx, 1)
movb %cl, (%r8, %rax, 1)
incq %rax
decq %rdx
cmpq %rdx, %rax
# important as %rdx can be -1
jl qstrrevloop
ret
# convert number in %rax to string (as unsigned)
# result goes into qstr and qstrl.
qstring_unsigned:
leaq qstr(%rip), %r8
leaq qstrl(%rip), %r9
movq $10, %rdi
# rsi holds the length
xorq %rsi, %rsi
qstruloop:
xorq %rdx, %rdx
# %rax <- %rax / 10
# %rdx <- %rax % 10
divq %rdi
# 48 is '0'
addq $48, %rdx
# put resulting char into the string
movb %dl, (%r8, %rsi, 1)
incq %rsi
test %rax, %rax
jnz qstruloop
# move length into qstrl
movq %rsi, (%r9)
# reverse the string
call qstr_rev
ret
# convert number in %rax to string (as signed)
# result goes into qstr and qstrl.
qstring_signed:
# for comments see qstring_unsigned
leaq qstr(%rip), %r8
leaq qstrl(%rip), %r9
# save to check for the sign later
movq %rax, %rcx
# compute absolute of rax
negq %rax
cmovs %rcx, %rax
movq $10, %rdi
xorq %rsi, %rsi
qstrsloop:
xorq %rdx, %rdx
divq %rdi
addq $48, %rdx
movb %dl, (%r8, %rsi, 1)
incq %rsi
test %rax, %rax
jnz qstrsloop
# add minus sign at the end of the string
movb $45, (%r8, %rsi, 1)
# rdi is 0, rdx is 1
xorq %rdi, %rdi
movq $1, %rdx
# set rdi to 1 if rcx is negative (rcx is the original number)
test %rcx, %rcx
cmovs %rdx, %rdi
# add rdi into the length of the string
addq %rdi, %rsi
movq %rsi, (%r9)
call qstr_rev
ret
# print number in %rax
qprint_unsigned:
# convert %rax to string
call qstring_unsigned
movq $1, %rax
movq $1, %rdi
leaq qstr(%rip), %rsi
leaq qstrl(%rip), %rdx
movq (%rdx), %rdx
syscall
ret
qprint_signed:
call qstring_signed
movq $1, %rax
movq $1, %rdi
leaq qstr(%rip), %rsi
leaq qstrl(%rip), %rdx
movq (%rdx), %rdx
syscall
ret