-
Notifications
You must be signed in to change notification settings - Fork 0
/
083.asm
219 lines (194 loc) · 4.6 KB
/
083.asm
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
format ELF64 executable 9
segment readable
f: db "0083_matrix.txt", 0 ;file name
wm equ 80 ;width of the matrix
lm equ 6400 ;length of the matrix array
ld equ 40960000 ;length of the distance array (lm^2)
inf equ 100:bd0000000 ;"infinity"
segment readable writable
result: times 10 db 0 ;empty string for printing the result later
db 10, 0
buf: rb 32000 ;buffer
mat: rd lm ;matrix
dis: rd ld ;distance matrix
segment readable executable
entry start
start:
mov eax, 5 ;file open
mov edi, f ;file name
mov esi, 0 ;read only
syscall
mov edi, eax ;file descriptor
mov eax, 3 ;read
mov esi, buf ;into buffer
mov edx, 32000 ;32000 bytes
syscall
mov edi, eax ;file descriptor
mov eax, 6 ;close
syscall
xor edi, edi ;reset registers for building the matrix
xor esi, esi
mov ebx, 10
xor ecx, ecx
next_n:
xor eax, eax ;reset eax, will hold the converted number
convert_n:
mov cl, [buf + esi]
cmp ecx, '0' ;is buf[esi] not a digit (i.e. ',' or '\n')?
jl n_done ;if yes, we are at the end of the number
mul ebx ;else convert string to number
sub ecx, '0'
add eax, ecx
inc esi
jmp convert_n
n_done:
mov [mat + 4 * edi], eax ;put current number in mat[edi]
inc esi ;increase edi and esi and continue
inc edi
cmp edi, 6400
jl next_n
xor esi, esi
inf_1:
xor edi, edi
inf_2:
cmp edi, esi
jne setinf
inc edi
setinf:
mov r8d, lm
imul r8d, esi
add r8d, edi
mov dword [dis + 4 * r8d], inf
inc edi
cmp edi, lm
jl inf_2
inc esi
cmp esi, lm
jl inf_1
xor esi, esi
dis_right_1:
xor edi, edi
dis_right_2:
mov r8d, wm
imul r8d, esi
add r8d, edi
mov r9d, lm
imul r9d, r8d
mov eax, [mat + 4 * r8d]
inc r8d
add r9d, r8d
mov ebx, [mat + 4 * r8d]
add eax, ebx
mov [dis + 4 * r9d], eax
inc edi
mov eax, wm
dec eax
cmp edi, eax
jl dis_right_2
inc esi
cmp esi, wm
jl dis_right_1
mov esi, lm
mov edi, 1
dis_left:
mov eax, [dis + 4 * edi]
mov [dis + 4 * esi], eax
add esi, lm
inc esi
add edi, lm
inc edi
cmp esi, ld
jl dis_left
xor esi, esi
dis_down_1:
xor edi, edi
dis_down_2:
mov r8d, wm
imul r8d, esi
add r8d, edi
mov r9d, lm
imul r9d, r8d
mov eax, [mat + 4 * r8d]
add r8d, wm
add r9d, r8d
mov ebx, [mat + 4 * r8d]
add eax, ebx
mov [dis + 4 * r9d], eax
inc edi
cmp edi, wm
jl dis_down_2
inc esi
mov eax, wm
dec eax
cmp esi, eax
jl dis_down_1
mov esi, lm
imul esi, wm
mov edi, wm
dis_up:
mov eax, [dis + 4 * edi]
mov [dis + 4 * esi], eax
add edi, lm
inc edi
add esi, lm
inc esi
cmp esi, ld
jl dis_up
xor edi, edi
fma_1:
xor esi, esi
fma_2:
xor edx, edx
fma_3:
mov r8d, lm
imul r8d, esi
add r8d, edx
mov eax, [dis + 4 * r8d]
mov r9d, lm
imul r9d, esi
add r9d, edi
mov ebx, [dis + 4 * r9d]
mov r10d, lm
imul r10d, edi
add r10d, edx
mov ecx, [dis + 4 * r10d]
add ebx, ecx
cmp eax, ebx
jle continue_fma
mov [dis + 4 * r8d], ebx
continue_fma:
inc edx
cmp edx, lm
jl fma_3
inc esi
cmp esi, lm
jl fma_2
inc edi
cmp edi, lm
jl fma_1
mov edi, lm
dec edi
mov eax, [dis + 4 * edi]
add eax, [mat]
add eax, [mat + 4 * edi]
shr eax, 1
mov ebx, 10
mov ecx, 9
convert_result:
xor edx, edx
div ebx
add edx, '0'
mov [result + ecx], dl
dec ecx
test eax, eax
jnz convert_result
print:
mov eax, 4
mov edi, 1
mov esi, result
mov edx, 12
syscall
exit:
mov eax, 1
xor edi, edi
syscall