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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
.section .data
newline:
.byte 10 # '\n'
tab:
.byte 9 # '\tab'
# --------------------------------------------
# FUNCTION: print_tab
# PURPOSE : print a tab character ('\t')
# INPUTS :
# OUTPUTS :
# CLOBBERS: rax, rdi, rsi, rdx
# --------------------------------------------
.globl print_tab
.type print_tab, @function
print_tab:
movq $1, %rax # write
movq $1, %rdi # stdout
movq $tab, %rsi # load tab character
movq $1, %rdx # 1 byte
syscall
ret
# --------------------------------------------
# FUNCTION: print_newline
# PURPOSE : print a newline character ('\n')
# INPUTS :
# OUTPUTS :
# CLOBBERS: rax, rdi, rsi, rdx
# --------------------------------------------
.globl print_newline
.type print_newline, @function
print_newline:
movq $1, %rax # write
movq $1, %rdi # stdout
movq $newline, %rsi # load newline character
movq $1, %rdx # 1 byte
syscall
ret
# --------------------------------------------
# FUNCTION: print_buffer
# PURPOSE : take a buffer of coordinates and print each coordinate on a line
# INPUTS : rdi = pointer to buffer, rsi = number of coordinates
# OUTPUTS :
# CLOBBERS: rax, rdi,
# --------------------------------------------
.globl print_buffer
.type print_buffer, @function
print_buffer:
cmpq $0, %rsi
jle done # if n > 0 print_coordinate
movq %rdi, %rdx # keep pointer here, rdi will be used for printNum
loop:
# print x and tab
movq (%rdx), %rdi # load x
call printNum
push %rdx # save pointer
push %rsi # save n
call print_tab
pop %rsi # retrieve n
pop %rdx # retrieve pointer
# print y and newline
movq 8(%rdx), %rdi # load y
call printNum
push %rdx # save pointer
push %rsi # save n
call print_newline
pop %rsi # retrieve n
pop %rdx # retrieve pointer
# move to next coordinate and decq n
addq $16, %rdx
decq %rsi
cmpq $0, %rsi
jg loop
done:
ret
# Print RDI as an unsigned integer without any new line.
# Note: the function does not follow the ordinary calling convention,
# but restores all registers.
.type printNum, @function
.globl printNum
printNum:
push %rbp
movq %rsp, %rbp
# save
push %rax
push %rdi
push %rsi
push %rdx
push %rcx
push %r8
push %r9
movq %rdi, %rax # arg
movq $0, %r9 # digit count
.LprintNum_convertLoop:
movq $0, %rdx
movq $10, %rcx
idivq %rcx
addq $48, %rdx # '0' is 48
push %rdx
addq $1, %r9
cmpq $0, %rax
jne .LprintNum_convertLoop
.LprintNum_printLoop:
movq $1, %rax # sys_write
movq $1, %rdi # stdout
movq %rsp, %rsi # buf
movq $1, %rdx # len
syscall
addq $8, %rsp
addq $-1, %r9
jne .LprintNum_printLoop
# restore
pop %r9
pop %r8
pop %rcx
pop %rdx
pop %rsi
pop %rdi
pop %rax
movq %rbp, %rsp
pop %rbp
ret
|