Používáme instrukci K (kopíruj konstantu), abychom si do registru A připravili písmeno. Potom instrukcí V (výstup) vypíšeme obsah registru A. Tohle je v programu napsané čtyřikrát za sebou pro všechna čtyři písmena A, H, O, J.
K A A
V A
K A H
V A
K A O
V A
K A J
V A
Z
Do registru A si uložíme písmeno A. Použijeme instrukci podmíněného skoku M (skoč, pokud je menší), aby se program opakoval skoro od začátku, dokud v registru A nebude písmeno G. Porovnání zařídí instrukce H (porovnej registr s hodnotou). Pomocí instrukce J (přičti jedničku) budeme posouvat obsah registru A o jedno písmeno v abecedě.
K A A
V A
J A
H A G
M D
Z
Nejprv shrňme, co nás obtěžuje ve hře na počítač:
Pro pochopení jazyka Assembler používáme simulátor počítače. Naší hře se hodně podobá, takže není těžké programy přeložit z jednoho jazyka do druhého.
V simulátoru počítače je trochu jinak zařízený výstup než v naší hře. Překladač se snaží tuhle nesrovnalost vyřešit s použitím registru D. Programy, které používají registr D, se nepřeloží správně.
Program se pokouší řešit sudoku 4×4 doplňováním číslice, která v některé buňce zbývá jako poslední možnost. Vstup je zapsaný přímo na začátku programu. Aby program byl kratší, používáme číslice 1, 2, 4, 8 a nevyplněná místa označujeme mezerou nebo nulou.
Sudoku na vyzkoušení si můžete nechat vygenerovat třeba na webu 1sudoku.com
jmp <u>main_loop</u>
<u>touched:</u> DB 0
<u>i_cell:</u> DB 0
<u>data:</u>
DB " 4 "
DB "1 4"
DB " 8"
DB " 2 "
<u>main_loop:</u>
mov [<u>touched</u>], 0
mov [<u>i_cell</u>], 0
<u>cell_loop:</u>
<i>; c: taken (bits)</i>
mov a, [<u>i_cell</u>]
add a, <u>data</u>
mov c, [a]
and c, 15
cmp c, 0
jnz <u>is_taken</u>
<i>; d: index of a neighbor</i>
mov d, 0
<u>neighbor_loop:</u><i>; a, b used for computation</i>
<i>; row neighbor</i>
<i>;index = (i_cell & 12) + j_cell</i>
mov a, [<u>i_cell</u>]
and a, 12
or a, d
add a, <u>data</u>
or c, [a]
<i>; column neighbor</i>
<i>;index = (j_cell * 4) + (i_cell & 3)</i>
mov a, d
shl a, 2
mov b, [<u>i_cell</u>]
and b, 3
or a, b
add a, <u>data</u>
or c, [a]
<i>; block neighbor</i>
<i>;index = (j_cell & 1) | ((j_cell & 2) * 2) | (i_cell & 10)</i>
mov a, d
and a, 1
mov b, d
and b, 2
shl b, 1
or a, b
mov b, [<u>i_cell</u>]
and b, 10
or a, b
add a, <u>data</u>
or c, [a]
inc d
cmp d, 4
jb <u>neighbor_loop</u>
not c
and c, 15
cmp c, 1
je <u>not_taken</u>
cmp c, 2
je <u>not_taken</u>
cmp c, 4
je <u>not_taken</u>
cmp c, 8
je <u>not_taken</u>
jmp is_taken
<u>not_taken:</u>
or c, '0'
mov a, [<u>i_cell</u>]
add a, <u>data</u>
mov [a], c
mov a, [<u>touched</u>]
inc a
mov [<u>touched</u>], a
<u>is_taken:</u>
mov a, [<u>i_cell</u>]
inc a
mov [<u>i_cell</u>], a
cmp a, 16
jb <u>cell_loop</u>
mov a, [<u>touched</u>]
cmp a, 0
jnz <u>main_loop</u>
mov a, <u>data</u>
mov b, 232
<u>print_loop:</u>
mov c, [a]
mov [b], c
inc a
inc b
cmp a, <u>main_loop</u>
jb <u>print_loop</u>
hlt