aboutsummaryrefslogtreecommitdiff
path: root/src/outputGenerator.s
blob: 34377ba34674861e92fecbf6dc72842b91b3c8ce (plain)
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
143
144
.section .data
newline: 
    .byte 10             # '\n'

tab:
    .byte 9              # '\tab'

.section .text
# --------------------------------------------
# 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 print_num

loop:
    movq (%rdx), %r15       # Pointer element

    # print x and tab
    movq (%r15), %rdi       # Get first number from element
    call print_num          # Print it 
    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(%r15), %rdi      # Get the second number
    call print_num          # Print it
    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 $8, %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 print_num, @function
.globl print_num
print_num:
	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
.Lprint_num_convertLoop:
	movq $0, %rdx
	movq $10, %rcx
	idivq %rcx
	addq $48, %rdx # '0' is 48
	push %rdx
	addq $1, %r9
	cmpq $0, %rax   
	jne .Lprint_num_convertLoop
.Lprint_num_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 .Lprint_num_printLoop

	# restore
	pop %r9
	pop %r8
	pop %rcx
	pop %rdx
	pop %rsi
	pop %rdi
	pop %rax

	movq %rbp, %rsp
	pop %rbp
	ret