Hra na počítač

Základní pojmy

Program, co vypíše AHOJ

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

Program, co vypíše ABCDEF

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

Assembler

Nejprv shrňme, co nás obtěžuje ve hře na počítač:

Výrazné rysy Assembleru

Překladač do jazyka Assembler

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ě.

Kód hry na počítač

Kód v Assembleru

Ukázka: řešení sudoku

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 &amp; 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 &amp; 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 &amp; 1) | ((j_cell &amp; 2) * 2) | (i_cell &amp; 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