-
Notifications
You must be signed in to change notification settings - Fork 0
/
code.asm
211 lines (190 loc) · 2.89 KB
/
code.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
; Sudoku Solver in x86 Assembly
section .data
; buffer of 168 bytes
buffer: db 168 dup(0)
buffer_len: equ $-buffer
section .text
global _start
_start:
; read input
mov rax, 3
mov rbx, 0
mov rcx, buffer
mov rdx, buffer_len
int 80h
; prepare arguments for main loop
push -1 ; current value
push 0 ; y position
push 0 ; x position
call start_main_loop
add rsp, 24
; print output
mov rax, 4
mov rbx, 1
mov rcx, buffer
mov rdx, buffer_len
int 80h
; exit
mov rax, 1
mov rbx, 0
int 80h
get_value:
mov rdx, (buffer)
imul rax, 2
add rdx, rax
imul rbx, 9
imul rbx, 2
add rdx, rbx
movzx rax, byte [rdx]
sub rax, '0'
mov [rbp+32], rax
jmp main_loop
start_main_loop:
push rbp
mov rbp, rsp
main_loop:
; get arguments
mov rax, [rbp+16] ; x
mov rbx, [rbp+24] ; y
mov rcx, [rbp+32] ; current value
; check if finish
cmp rbx, 9
je finish
; if don't have value yet
cmp rcx, -1
je get_value
; if value alreadey exists
cmp rcx, 0
jg next
; try values
jmp try_values
next:
; go next value in line
add rax, 1
; if end of line, go next line
cmp rax, 9
jl next_next
mov rax, 0
add rbx, 1
next_next:
mov [rbp+16], rax
mov [rbp+24], rbx
mov rcx, -1
mov [rbp+32], rcx
jmp main_loop
goback:
pop rax
pop rbx
mov [rbp+16], rax
mov [rbp+24], rbx
mov rdx, (buffer)
imul rax, 2
add rdx, rax
imul rbx, 9
imul rbx, 2
add rdx, rbx
movzx rcx, byte [rdx]
sub rcx, '0'
mov rax, 0
add rax, '0'
mov [rdx], al
mov rax, [rbp+16]
mov rbx, [rbp+24]
jmp try_values_loop
try_values:
; try values from 1 to 9
mov rcx, 0
try_values_loop:
add rcx, 1
cmp rcx, 10
je goback ; TODO : backtracking
push rbx
push rax
push rcx
call check_line
cmp rax, 1
je try_values_continue
pop rcx
pop rax
pop rbx
jmp try_values_loop
try_values_continue:
call check_column
cmp rax, 1
je try_values_success
pop rcx
pop rax
pop rbx
jmp try_values_loop
try_values_success:
mov rcx, [rsp]
mov rax, [rsp+8]
mov rbx, [rsp+16]
mov rdx, (buffer)
imul rax, 2
add rdx, rax
imul rbx, 9
imul rbx, 2
add rdx, rbx
add rcx, '0'
mov [rdx], cl
pop rcx
pop rax
pop rbx
push rbx
push rax
jmp next
check_line:
push rbp
mov rbp, rsp
; for x 0 to 8*2 in line y
mov rax, 0
check_line_loop:
cmp rax, 18
je success
mov rcx, [rbp+16] ; value to try
mov rbx, [rbp+32] ; y
mov rdx, (buffer)
imul rbx, 9
imul rbx, 2
add rdx, rbx
add rdx, rax
movzx rdx, byte [rdx]
sub rdx, '0'
cmp rdx, rcx
je fail
add rax, 2
jmp check_line_loop
check_column:
push rbp
mov rbp, rsp
; for y 0 to 8 in column x
mov rbx, 0
check_column_loop:
cmp rbx, 9
je success
mov rcx, [rbp+16] ; value to try
mov rax, [rbp+24] ; x
mov rdx, (buffer)
imul rax, 2
add rdx, rax
mov rax, rbx
imul rax, 9
imul rax, 2
add rdx, rax
movzx rdx, byte [rdx]
sub rdx, '0'
cmp rdx, rcx
je fail
add rbx, 1
jmp check_column_loop
success:
mov rax, 1
jmp finish
fail:
mov rax, 0
jmp finish
finish:
mov rsp, rbp
pop rbp
ret