Začneme týmto jednoduchým príkladom. Chceme zmazať obrazovku v textovom móde a využijeme na to priamy prístup k nej. Obrazovka začína na B800:0000h a má 80 stĺpcov a 25 riadkov (v základnom textovom móde) po dvoch bajtoch. Prvý je ASCII kód znaku, druhý je farba znaku.
[BITS 16]
[ORG 0x0100]
[SECTION .text]
MOV AX,0B800H ;hexadecimálne číslo musí začínať číslicou, aby nebolo zamýlené s názvom návestia, preto ho treba zapísať ako 0B800h a nie B800h
MOV ES,AX ;segmentový register ES možno napĺňať len cez AX
MOV CX,80*25
MOV AX,7*256+' ' ;farbou 7 (biela) "vymaz" obrazovku medzerami
REP STOSW
MOV AX,4C00h
INT 21h
Ďalší príklad vypíše pevne zvolené číslo v pevne zvolenej sústave (v rozsahu 2 - dvojková - až 16 - hexidecimálna). Na výpis využíva službu DOSu.
[BITS 16]
[ORG 0x0100]
[SECTION .text]
MOV AX,12345 ;vypisované číslo v rozsahu 0 až 65535
MOV BL,16 ;základ sústavy v rozsahu 2 až 16
MOV DI,16 ;číslo budeme zapisovať od konca - od najnižšej čílice
dalej:
DEC DI ;ďalšia číslica
XOR DX,DX ;DX<-0
DIV BX ;do DX ďalšia číslica
MOV SI,DX
MOV DL,[SI+cislice] ;zisti znak pre dané číslo...
MOV [DI+vypis],DL ;...a vypíš ho
AND AX,AX
JNZ dalej ;znova, dokým nebude AX=0, tzn. dokým nevypíšeme všetky číslice
MOV DX,text ;do DX adresu prvého textu
MOV AH,09h ;číslo služby...
INT 21h ;...určenej na vypisovanie textu
MOV DX,vypis
ADD DX,DI ;výpis čísla začneme od prvej - najvyššej, teda naposledy zapísanej číslice
MOV AH,09h
INT 21h
MOV AX,4C00h
INT 21h
[SECTION .data] ;tak takto sa definuje oblasť premenných
cislice DB '0123456789ABCDEF' ;zoznam znakov číslic
text DB 'Cislo = $' ;vypisovaný text ukončený znakom $
vypis TIMES 16 DB 0
DB '$' ;najviac šestnásťznakové číslo, ktoré bude vypísané - cez direktívu TIMES sa definuje poľe z rovnakých údajov jednoduchšie
Tento program pracuje s číslom získaného zo vstupu (z klávesnice, v prostredí NASMIDE treba vstup zadať v menu cez položku parameters), v rozsahu slova (0 až 65535). Hľadá jeho odmocninou v podstate metódou pokus - omyl. Skúša postupne nastavovať jednotlivé bity hľadaného výsledku (od najvyššieho) a tak toto číslo umocní. Ak je mocnina väčšia, nastavovaný bit treba opäť vynulovať.
[BITS 16]
[ORG 0x0100]
[SECTION .text]
MOV DX,vstup
MOV CX,7 ;...sedem znakov, keďže dva z nich budú znamenať ukončenie riadku, teda stlačenie enteru (0Dh, 0Ah)...
MOV BX,0 ;...do pamäte od miesta návestia vstup
MOV AH,3Fh
INT 21h
SUB AX,2 ;v AX je počet znakov zo vstupu, no treba odstrániť znak enter
OR AX,AX
JZ koniec ;ak nie je vstup, skonči
MOV CX,AX ;do CX počet znakov
MOV DI,vstup
MOV BX,10 ;ideme previesť vstup v desiatkovej sústave do registra AX
XOR AX,AX
XOR DH,DH ;vynuluj AX a DH
testuj:
MUL BX ;vynásob aktuálny výsledok desiatimi
MOV DL,[DI] ;prečítaj ďalší znak
SUB DL,'0' ;zmeň ASCII znak na číslo 0 až 9
INC DI ;presuň ukazovateľ na ďalší znak
CMP DL,0
JC koniec ;ak nie je číslo v rozsahu 0 až 9, tak skonči
CMP DL,10
JNC koniec
ADD AX,DX ;pripočítaj čílicu k aktuálnemu výsledku
LOOP testuj ;t.j. SUB CX,1 a JNZ testuj - jednoduchý cyklus
JMP pokracuj
koniec:
MOV AX,4C00h
INT 21h ;bol nevhodný vstup - skonči
pokracuj:
MOV CX,AX ;do CX odmocňované číslo
MOV BL,10000000b ;začneme najvyšším bitom
XOR BH,BH ;BH<-0
MOV DL,2
hladaj:
ADD BH,BL ;pokusne pripočítaj skúmaný bit
MOV AL,BH
MUL AL ;umocni predpokladanú odmocninu...
CMP CX,AX ;...a porovnaj ju s odmocňovaným číslom
JNC dobre
SUB BH,BL ;trochu sme to prešvihli, odpočítaj ten bit späť
dobre:
MOV AL,BL ;ak je všetko v poriadku...
XOR AH,AH
DIV DL
MOV BL,AL ;posuň BL na ďalší bit - vydeľ ho dvoma a zarotuje doprava
OR AL,AL
JNZ hladaj ;ak sme nepreskúmali všetky bity, pokračuj
MOV AL,BH
MUL AL
SUB CX,AX ;ešte raz výsledné číslo umocni a získaj zvyšok po delení
MOV AL,BH
XOR AH,AH
MOV BX,10
MOV DI,3
dalej1: ;výpis registra AX - výsledku - procedúrou ako v programe výpis čísla
DEC DI
XOR DX,DX
DIV BX
MOV SI,DX
MOV DL,[SI+cislice]
MOV [DI+vypis1],DL
AND AX,AX
JNZ dalej1
MOV DX,text1
MOV AH,09h
INT 21h
MOV DX,vypis1
ADD DX,DI
MOV AH,09h
INT 21h
MOV DI,3
MOV AX,CX
dalej2: ;výpis registra CX - zvyšku - podobne
DEC DI
XOR DX,DX
DIV BX
MOV SI,DX
MOV DL,[SI+cislice]
MOV [DI+vypis2],DL
AND AX,AX
JNZ dalej2
MOV DX,text2
MOV AH,09h
INT 21h
MOV DX,vypis2
ADD DX,DI
MOV AH,09h
INT 21h
MOV AX,4C00h
INT 21h
[SECTION .data]
vstup TIMES 7 DB 0 ;miesto pre vstup z klávesnice
cislice DB '0123456789' ;znaky a texty na výpis ako v programe výpis čísla
text1 DB 'Odmocnina = $'
vypis1 TIMES 3 DB 0
DB '$'
text2 DB ', zvysok = $'
vypis2 TIMES 3 DB 0
DB '.$'
Posledný program je pokus o šetrič obrazovky. Vypisuje štyridsať znakov "usmievavej tváre" (znak 01h ASCII) a pohybuje nimi rôznymi smermi. Ak nejaké "vypadne" z obrazovky, program vygeneruje ďalší znak.
[BITS 16]
[ORG 0x0100]
[SECTION .text]
zaciatok:
MOV AX,0B800h
MOV ES,AX
XOR DI,DI
MOV CX,80*25
MOV AX,7*256+' '
REP STOSW
MOV SI,39*2 ;vypisujeme od 39. znaku po znak 0. - spolu 40 znakov - z dvojbajtovej tabuľky
MOV AH,01h
INT 16h
JZ cyklus ;zisti, či bol stlačený znak, a skonči, ak bol
XOR AH,AH ;ešte ho však vyber zo zásobníka
INT 16h
MOV AX,4C00h
INT 21h
cyklus:
MOV CX,[SI+poz] ;zisti, či je daný znak platný (po spustení nie je zatiaľ ani jeden)
OR CX,CX
JNZ vypis ;ak je v poriadku, vypíš ho, ináč pokračuj jeho novým vygenerovaním
CALL random ;do DX náhodné číslo, zavolá procedúru random, po návrate z nej pokračuje ďalším príkazom
MOV CX,DX ;a teraz sa z DX pokúsime "vyextrahovať" smer nového znaku (s výnimkou najvyššieho - nevyužitého bitu tri najvyššie bity horného bajtu), jeho riadok (zvyšné štyri bity horného bajtu), farbu (najvyššie dva bity dolného bajtu) a stĺpec (zvyšných šesť bitov dolného bajtu)
AND CX,0000111100111111b ;maska pre ypsilónovú a ixovú súradnicu znaku...
ADD CX,5*256+9 ;...ktoré boli vygenerované v rozsahu 0 až 15 (pripočítaním 5 upravené na 5 až 20) a 0 až 63 (pripočítaním 9 upravené na 9 až 72)
MOV [SI+poz],CX ;zapíš nové súradnice do tabuľky
AND DX,0111000011000000b ;maska pre smer a farbu generovaného znaku
MOV [SI+info],DX ;zapíš nové informácie do tabuľky
vypis:
MOV DL,160 ;výpis znaku, v CX ostali jeho súradnice
SUB CX,0101h ;úprava z 1..80 a 1..25 na 0..79 a 0..24
ADD CL,CL ;vynásob súradnicu x dvoma - jeden znak zaberá v pamäti obrazovky dva bajty
MOV AL,CH
MUL DL ;a vynásob súradnicu y 80*2 z rovnakého dôvodu
XOR CH,CH
ADD AX,CX
MOV DI,AX ;adresu znaku na obrazovke do DI
MOV BX,[SI+info] ;zisti smer a farbu znaku
MOV AL,BL
MOV BL,01000000b
XOR AH,AH
DIV BL ;farba je na prvých dvoch najvyšších bitoch dolného bajtu - treba ju posunúť na najnižšiu pozíciu v bajte...
ADD AL,00001100b ;...a pripočítať k farbe 12, aby bola svetlá - výsledné farby teda budú svetločervená, svetlofialová, žltá a biela
MOV AH,AL
MOV AL,1 ;znak 01h - usmievavá tvár
STOSW ;a výpis
MOV BL,00100000b/2 ;rovnako posuň smer, ale až na druhý najnižší bit - tabuľka je dvojbajtová
MOV AL,BH
XOR AH,AH
DIV BL
MOV DI,AX
MOV CX,[SI+poz] ;do CX aktuálnu pozíciu znaku
ADD CX,[DI+tab] ;a k nej pripočítať "rýchlosť" podľa tabuľky
OR CH,CH ;zistíme, či znak náhodou nevyšiel z obrazovky
JZ zrus
CMP CH,26
JNC zrus
OR CL,CL
JZ zrus
CMP CL,81
JC nechaj
zrus:
XOR CX,CX ;vyšiel - zruš ho
nechaj:
MOV [SI+poz],CX ;zapíš novú pozíciu znaku
SUB SI,2 ;choď na ďalší znak
JNC cyklus
XOR AX,AX ;všetky znaky vypísané - teraz už len čakacia slučka, aby sa tie znaky príliš nemihali pred očami...
MOV ES,AX ;...bez nej by sa pri súčasnej rýchlosti počítačov tie znaky ledva dali rozpoznať
MOV AL,[ES:046Ch]
cakaj:
CMP AL,[ES:046Ch]
JZ cakaj ;počká na zmenu časovača, ktorý sa mení každých 55 milisekúnd, teda 18.2 krát za sekundu
JMP zaciatok ;a znova na začiatok
random: ;procedúra na generovanie náhodného čísla
MOV BX,0 ;naposledy vygenerované číslo
MOV DH,BL ;neviem, ako táto procedúra funguje, je odpísaná z knihy Assembler a ZX Spectrum 2, ktorej autori jú odpísali z iného programu...
MOV DL,253 ;v každom prípade generuje spoľahlivo všetky čísla v rozsahu 0 až 65535
MOV AL,BH
SUB DX,BX
SBB AL,0
SBB DX,BX
SBB AL,0
MOV BL,AL
MOV BH,0
SBB DX,BX
JNC random1
INC DX
random1:
MOV [random+1],DX ;zapíš nové náhodné číslo...
RET ;...a vráť sa z procedúry
[SECTION .data]
tab DW 0FFFFh,0FF00h,0FF01h,00001h,00101h,00100h,001FFh,000FFh ;tabuľka rýchlostí v závislosti od smerov, od smeru vľavo hore smerom podľa ručičkových hodín, horný bajt je zápis "rýchlosti" y, dolný bajt je zápis "rýchlosti" x, z možností -1 (=0FFh=255), tzn. hore/vľavo, 0 a 1, tzn. dole/vpravo
poz TIMES 40 DW 0 ;pozícia znakov na začiatku - všetky sú nulové, aby boli nanovo vygenerované
info TIMES 40 DW 0 ;informácie o znakoch - smer a farba