Assebly feladatok Bevezetés A feladatok mindegyike működőképes. A programkódok sok esetben tartalmaznak felesleges, vagy „logikátlan” megoldásokat. Ezeket a bemutatás során a hallgatókkal együtt kell optimalizálni. Ez segíti a gondolkodást és az odafigyelést. A feladatok ismertetését meg kell előzze az X86-os processzor regiszter szintű áttekintése, valamint a főbb utasításcsoportok tárgyalása. ADD SUB DEC INC DEC NOP MUL DIV
SHR SHL
JZ JNZ JC JNC
NOT NEG AND XOR
CALL RET
JMP
POP PUSH
Ezt követően ismertetni kell a szoftver megszakítás fogalmát és szükségességét. INT Ismertetni kell a BIOS és DOS megszakítások jellemzőit. (nem kell a megszakításokat megtanulni) Az egyes megszakítások használatához jól használható a HELP nevű program, ami minden gépre telepítve van. Ismertetni kell a DOS programfuttatási mechanizmusát és annak következményeit. .COM és EXE programok főbb jellemző.
0. feladat (A.asm) Írjunk ki egy "A" betűt! A program IBM PC-n (kézikönyv alapján):
B4 02 B2 41 CD 21 CD 20 hex 180 2 178 65 205 33 205 32 dec A fenti program kipróbálása: c:\>c:\copy con proba.com ... 1 file(s) copied c:\> proba A c:\>_ A második sorba a számokat beírjuk a billentyűzetről (Alt+ az aláhúzott sor számjegye), a végén Ctrl+z és Enter. A fenti művelet után kapott „proba.com” programot el lehet indítani! A fenti program Assembly nyelvű megfelelője: Hex B4 B2 CD CD
dec 02 41 21 20
mnemonik mov mov int int
A tagolás általános formája: mov ah,2 mov dl,41h ;”A” int 21h int 20h
utasításkód ah, dl, 21 20
adat (operandus) 2 41h h h
megjegyzés ;”A”
1. feladat (szamlalo.asm) A program célja, megismertetni az assembly program felépítését. A program kiír a képernyőre egy üzenetet, valamint számlálja az „A” billentyű leütését. A számlálás 0-tól indul, 9 után az ASCII tábla megfelelő jelei kerülnek a képernyőre. Program bemutatása: 1. Egy üres, de fordítható és futtatható keret elkészítése. Ez a keret lesz az alapja a további programoknak is. 2. A kész keretbe egy üzenet kerül. Ez a klasszikus „HELLO WORLD” program. Ennek segítségével bemutatásra kerül az egyszerű string kiírás az Ah09, INT21h DOS funkcióval. 3. Létre kell hozni egy programhurkot. Ez egy egyszerű JMP utasítással történik. Biztosítani kell a hurokból való kilépést, hogy ne legyen végtelen ciklus. Ehhez ismertetni kell az AH00, INT16h funkciót, valamint meg kell írni egy feltételvizsgálatot. A program forráskódja: Code Segment assume CS:Code, DS:Data, SS:Stack
Start
Start: mov mov
ax, Code DS, AX
mov mov mov mov int
ah, 02h bh, 0 dh, 10 dl, 0 10h
mov mov int
dx, offset uzenet1 ah, 09 21h
;Uzenet1 kiirasa
mov mov int
dx, offset szamlalo ah, 09 21h
;szamlalo kiirasa
mov mov int
dx, offset uzenet2 ah, 09 21h
;Uzenet2 kiirasa
Kurzor pozícionálás
Kiir:
Üzenet1 kiírás
;Cursor a 10. sorra ;Cursor a 0. oszlora
Üzenet2 kiírás Üzenet3 kiírás
Bevitel
ESC ?
igen
Program vége
nem “a” ? nem
igen
Számláló növelésel
Bevitel: xor int
ax,ax 16h
;Varakozas egy billentyu leutesre
mov cmp jz mov
ah,27 ah,al Program_Vege ah,'a'
cmp jz jmp
ah,al Szamol Bevitel
;Kilepes gombja
Vizsg:
Szamol: mov mov inc mov jmp
di,offset szamlalo al, [di] al [di], al Kiir
Program_Vege: mov ax, 4c00h int 21h uzenet1: uzenet2: szamlalo:
db db db
"Az A billentyu $" " alkalommal volt leutve$" "0$"
Code Ends Data
Segment
Data
Ends
Stack Segment Stack Ends End Start Házi feladat: Egészítse ki a programot úgy, hogy a számlálás 00-99 –ig történjen. Kezelje le a túlcsordulásokat, ne engedje a számlálót 99 elérése után növelni, illetve 00 után csökkenteni.
2. feladat (konv.asm) A program célja, gyakorolni az eddig megismert funkciókat, valamint megismerni a memória tartalmának futásidőben történő módosítását. A program egy négyjegyű decimális számot vár, amit a billentyű segítségével lehet bevinni. A számot egy, a memóriában elhelyezett változó tárolja, karakterenként ASCII kódban. A program törli a képernyőt és csak számokat fogad el. Egyéb gombok megnyomására hibaüzenetet ad. Program bemutatása: 1. A programot el kell készíteni a tároló programág kivételével. A tároló ágat egy JMP Bevitel utasítással kell helyettesíteni. Az így lefordított program látszólag semmit sem tesz, ha számot ütünk le, minden egyéb billentyű hatására hibaüzenetet küld. ESC billentyű leütésére a program megáll. 2. A teljesen elkészített program a számok leütése esetén a képernyőre kiírja az eddig begépelt számsort. Ha a begépelt számok hossza elérte a 4-et, az kiíródik a képernyőre, majd a vezérlés átadódik az „üres buborékkal” jelölt programágra. Mivel ez utóbbi nincs megírva, a program a kilépés ágon folytatódik. A program forráskódja: Progi SEGMENT ASSUME CS:Progi, DS:Progi, SS:Stack Start: mov mov
ax,Progi ds,ax
mov
di,offset ertek
mov int
ax,03 ;Keprenyo torles 10h
Bevitel: xor int
ax,ax 16h
mov mov int mov
bx,ax ax,03 10h ax,bx
mov cmp jz
ah,27 ah,al Kilep
;Varakozas egy billentyu leutesre ;ax elmentese bx-be ;Kepernyo torles ;ax visszaallitasa ;Kilepes gombja
mov mov
cx,10 ah,'0'
;Ennyiszer fut a VIZSG rutin
cmp jz inc loop
ah,al Tarol ah Vizsg
;Itt vegignezzuk 0-9-ig, hogy a bevitt karakter szam-e? ;Ugrunk, ha szam
mov mov mov mov int
ah,02h bh,0 dh,10 dl,0 10h
;Itt megyunk tovabb, ha nem szam
mov mov int
dx,offset Hiba ah,09 21h
jmp
Bevitel
mov inc mov mov
[di],al di al,'$' [di],al
mov mov mov mov int
ah,02h bh,0 dh,05 dl,28 10h
mov mov int
dx,offset ertek ah,09 21h ;Az eddig begepelt szamok kiirasa
mov add mov sub jnz
ax, offset ertek ax,04 ;Ha a begepelt szam 4 helyerteku, akkor bevitel vege bx,di ax,bx Bevitel ;Meg nincs meg a negy, mert AX+4 nagyobb mint DI
Vizsg:
;Cursor a 10. sorra ;Cursor a 0. oszlora ;Hibauzenet kiirasa
Tarol: ;Az ERTEK memoriahelyre letesszuk a bevitt szamot ;Itt meg ASC kodban van a szam ;String lezaro karakter ;Most kerult a sztring vegere a dollar jel
;Cursor a 5. sorra ;Cursor a 28. oszlora
mov mov mov mov int
ah,02h bh,0 dh,07 dl,0 10h
mov mov int
dx,offset uzenet ah,09 21h
mov int
ax,4c00h 21h
;Cursor a 7. sorra ;Cursor a 0. oszlora ;Bevitel vege
Kilep:
Start Képernyő törlés
Bevitel Képernyő törlés
ESC ?
igen
Program vége
nem
Hiba db ertek db uzenet db
'Nem megengedett karakter!$' '*****$' 'Vege a bevitelnek$'
“0-9” ?
igen
Tárolás
nem
Progi ENDS
Kurzor pozícionálás
Kurzor pozícionálás
Hiba kiírás
Hiba kiírás
Stack segment Stack ENDS END START
Szám nem hossza 4 ? igen
3. feladat (labda.asm) A program célja az assembly rutinok időzítési lehetőségeinek bemutatása. Az időzítés az AH00, INT1Ah funkció segítségével történik. A program egy „labda” leesését szimulálja. A labdát egy „o” karakter szimbolizálja, amely fokozatosan gyorsulva esik le, majd visszapattan. A visszapattanás veszteségmentes, így a labda fokozatosan lassulva eléri a kiindulási pozíciót. Program bemutatása: 1. A programot először a késleltető rutinok nélkül kell megírni. A billentyűfigyelés helyett az AH00, INT16h funkcióval megvalósítható billentyűleütésre történő várakozást kell megírni. Így a program csak akkor lép a következő iterációra, ha lenyomunk egy billentyűt. Ellenőrizni kell, hogy a „labda” nem megy ki a képből. A legalsó pozíciót elérve felfelé mozog tovább, a legfelső pozíció elérését követően lefele halad. 2. A letesztelt programban módosítani kell a billentyűleütésre váró részt az AH01, INT16h funkcióra. Ez a funkció nem állítja meg a program futását, mindössze a FLAG-ek állapotát, illetve az AL értékét módosítja, ha volt billentyűleütés. Be kell fejezni a késleltető programrészt. A késleltetés alapeleme az AH00, INT1Ah funkció, mely a rendszeróra CX:DX regiszterpárba. Egy számlálóváltozás kb. 1/18 sec. A program forráskódja: Start SI:=1, DI:=0 T-1:=0
Poz < 5 ?
igen
∆T := 16
nem Képerny törlés
Poz < 10 ?
Kurzor pozícionálás
Poz < 15 ?
igen
∆T := 4
nem
Billenty figyelés
nem
∆T := 8
nem
Labda kirakás
ESC ?
igen
igen
Program vége
Poz < 20 ?
igen
∆T := 2
nem ∆T := 1
Óra beolvasás Eltelt id := T-T-1
T > ∆T ?
igen
T-1 := T
nem Poz = 0 ?
igen
SI := 1
nem Poz = 0 ? nem Képerny törlés Poz := Poz + SI
igen
SI := -1
Code Segment assume CS:Code, DS:Data, SS:Stack Start: mov mov
ax, Code DS, AX
Init: XOR DI,DI MOV SI, 1
;A labda helye (0. sor) ;Lefele indul a labda
XOR DX, DX PUSH DX
;Verembe a regi ido (most 0)
MOV AX, 3 INT 10H
;Karakteres videomod be (itt kepernyo torles)
MOV DX, DI MOV DH, DL
;Kepernyopozicionalas DI sorra es 40. karakterre ;Azert kell, mert DH-ba kell DI also
Torles:
MOV XOR MOV INT
DL, 40 BH, BH AH, 2 10H
MOV DX, offset Labda MOV AH, 9 INT 21H Kesleltet: MOV AH,01 int 16h jnz Program_Vege XOR INT POP PUSH MOV SUB
AH, AH 1Ah CX CX AX, DX DX, CX
;Labda kirakas
;Varakozas egy billentyu leutesre
;Ora beolvasasa CX:DX -be ;Regi ido kivetele a verembol ;Regi ido vissza a verembe ;Aktualis ido elmentese AX-be ;DX-BE IDO-REGI_IDO (eltelt ido)
PUSH AX
;AX elmentese
CMP JNC MOV JMP
DI, 5 Ido1 AL,16 Beallit
;Ha a labda y=0-5
CMP JNC MOV JMP
DI, 10 Ido2 AL,8 Beallit
CMP JNC MOV JMP
DI, 15 Ido3 AL,4 Beallit
CMP JNC MOV JMP
DI, 20 Ido4 AL,2 Beallit
;Sebessege 1/16
Ido1: ;Ha a labda y=6-10 ;Sebessege 1/8
Ido2: ;Ha a labda y=11-15 ;Sebessege 1/4
Ido3: ;Ha a labda y=16-20 ;Sebessege 1/4
Ido4: MOV AL,1 Beallit: XOR AH, AH CMP DX, AX POP
AX
JC
Kesleltet
;Sebessege 1
;Az ido beallitasa (AL*1/18sec) ;AX visszaallitasa
POP CX PUSH AX
;Regi ido kivetele a verembol ;Aktualis ido elmentese
CMP DI, 0 JZ Le
;Ha a labda fenn van
CMP DI, 25 JZ Fel
;Ha a labda lenn van
Mozgas: MOV DX, DI MOV DH, DL MOV XOR MOV INT
;Kepernyopozicionalas DI sorra es 40. karakterre ;Azert kell, mert DH-ba kell DI also
DL, 40 BH, BH AH, 2 10H
MOV DX, offset Ures MOV AH, 9 INT 21H
;Labda torlese
ADD DI, SI JMP Torles
;A labda uj pozicioja
MOV SI, 1 JMP Mozgas
;A mozgas iranya 1=lefele
MOV SI, -1 JMP Mozgas
;A mozgas iranya -1=felfele
Le:
FeL:
Program_Vege: POP CX mov ax, 4c00h int 21h Labda db Ures db
"O$" " $"
Code Ends Data
Segment
Data
Ends
Stack Segment Stack Ends End Start
;Verem uritese
1. önálló feladat (keret.asm) Írjon egy olyan programo, amely karakteres üzemmódban „*” karakterekkel bekeretezi a képernyőt. A program a keretet karakterenként rajzolja meg! Megoldási idő 20 perc. Az eddig megismert utasítások és megszakítások elegendőek a feladat megoldásához.
4. feladat (golyo.asm) A program célja bemutatni a parancssoros paraméterátadást. A hallgatók megismerik a DTA felépítését, szerepét, valamint annak elérését. A program az előző programhoz hasonlóan egy golyó leesését szimulálja. Paraméterként megadható a golyó vízszintes irányú kezdősebessége. Ekkor a test egy parabola pályán mozog, amit a program kirajzol. Paraméter nélkül indítva a programot, az egy alapértelmezett (10m/s) kezdősebességű testet szimulál. A számítás alapja: sy=1/2g*t2, sx=vx*t Program bemutatása: 1. A programot először a bemenő paramétereket feldolgozó rész nélkül kell megírni. Ekkor a program az alapértelmezett 10m/s kezdősebességgel induló test pályáját rajzolja ki. 2. A működő programot ki kell egészíteni a paraméter feldolgozó résszel. Az így megírt program szigorúan „/11” formátumban fogadja a paramétereket. Önálló gyakorlásként ajánlható a paraméter feldolgozás hibakezelésének megírása. Például a program ne számoljon a „/w2” paraméterrel. A program forráskódja: Code Segment assume CS:Code, DS:Data, SS:Stack Start: MOV DI, 80H
;DTA kezdocime ;Harom karakteres parametert varunk ;Az elso: /, masodi, haramdik: SZAM
MOV CX, 10 Keres: MOV CMP JZ INC LOOP JMP
DL, [DI] DL, "/" ParamKezdet DI Keres Default
ParamKezdet: INC DI MOV BL, [DI] SUB BL, 48 INC DI MOV BH, [DI] SUB BH, 48 MOV AX, 10
;Elso szamjegy (*10) ;Masodik szamjegy (*1)
MUL ADD MOV JMP
BL AL, BH CX, AX Init
Default: MOV CX, 10
;AL-ben a szam
;Alapertelmezett V0
Init: mov mov
ax, Code DS, AX
XOR DI,DI XOR SI,SI
;A golyo helye (0. sor) ;A golyo helye (0. oszlop)
XOR DX, DX PUSH DX
;Verembe az ido (most 0)
Torles: MOV AX, 3 INT 10H
;Karakteres videomod be (itt kepernyo torles)
MOV MOV MOV MOV XOR MOV INT
;Kepernyopozicionalas DI sorra ;Azert kell, mert DH-ba kell DI also ;Kepernyopozicionalas SI karakterre ;Azert kell, mert DH-ba kell DI also
Rajz: BX, DI DH, BL BX, SI DL, BL BH, BH AH, 2 10H
MOV DX, offset Labda MOV AH, 9 INT 21H
;Golyo kirakas
POP AX PUSH AX
;Ido kivetele ;Ido elmentese
MOV MUL SHR MOV
BL, AL BL AX, 1 DI, AX
;A szorzashoz BL toltodik AL-el ;Eredmeny AX-ben ;2-vel osztunk ;Beirjuk az uj Y koordinatat
POP INC
AX AX
;Ido kivetele ;Ido novelese
PUSH AX DEC AX
;Ido elmentese ;Pillanatnyi ido
MOV BL, CL MUL BL MOV SI, AX
;A szorzashoz BL toltodik CL-el (Vizszintes sebesseg) ;Eredmeny AX-ben ;Beirjuk az uj X koordinatat
CMP JNC CMP JNC
SI, 80 Var DI, 25 Var
JMP
Rajz
Var: XOR AX, AX INT 16H Program_Vege: POP CX mov ax, 4c00h int 21h Labda db
;Verem uritese
"O$"
Code Ends Data
Segment
Data
Ends
Stack Segment Stack Ends End Start Házi feladat: Egészítse ki a programot úgy, hogy a paraméter feldolgozása során a program kizárólag számokkal működjön. Hibás paraméter esetén adjon hibaüzenetet, mit egy tetszőleges billentyű megnyomásával nyugtázhat. Ezt követően a program fusson le az alapértelmezett kezdősebességgel.
5. feladat (pattog.asm) A program célja egy összetett feladaton történ gyakorlás. A program karakteres képernyőn jelenít meg egy karaktert („O” betű), amely 45 fokos szögben mozdul egy-egy karakter pozíciót arrébb minden egyes billentyűleütés hatására. Ha a szimbólum eléri a képernyő szélét, a mozgás iránya megváltozik. A program forráskódja: Code Segment assume CS:Code, DS:Data, SS:Stack Start: mov mov
ax, Code DS, AX
mov mov mov mov push push
dh, 10 dl, 20 ah, -1 al, -1 ax dx
;Y koordinata ;X koordinata ;y iranya ;X iranya
Main: ;***************************************************************** ; A karater torlese mov ah, 02h mov bh, 0 pop dx ;DL:X koordinata ;DH:Y koordinata push dx int 10h mov dx, offset ures ;”Space” kiirasa mov ah, 09 int 21h ;***************************************************************** pop dx ;DL:X koordinata ;DH:Y koordinata pop ax ;AH:X iranya ;AL:Y iranya ;***************************************************************** ; A szelso ertekek megadasa mov bh, 64 mov bl, 1
mov ch, 24 mov cl, 1 ;***************************************************************** add dl, al cmp dl, bh jnz tovabb1 mov al, -1 tovabb1: cmp dl, bl jnz tovabb2 mov al, 1 tovabb2: add cmp jnz mov tovabb3: cmp jnz mov tovabb4: push push
dh, ah dh, ch tovabb3 ah, -1 dh, cl tovabb4 ah, 1 ax dx
;***************************************************************** ; A karakter kirakasa mov ah, 02h mov bh, 0 pop dx ;DL:X koordinata ;DH:Y koordinata push dx int 10h mov dx, offset jel ;”O” kiirasa mov ah, 09 int 21h ;***************************************************************** xor ax,ax int 16h ;Varakozas egy billentyu leutesre mov cmp jz
ah,27 ;Kilepes gombja ah,al Program_Vege
jmp
Main
Program_Vege: mov ax, 4c00h int 21h ures: jel:
db db
" $" "0$"
Code Ends Data
Segment
Data
Ends
Stack Segment Stack Ends End Start Házi feladat: Alakítsa át a programot úgy, hogy az ütemezést időzítő segítségével oldja meg. A programból továbbra is biztosítsa a kilépés lehetőségét.
6. feladat (rajzolo.asm) A feladat célja bemutatni egy egyszerű grafikai program segítségével a közvetlen memóriacímzést (grafikus VGA 320*200). A program a kurzor mozgató gombok segítségével folytonos vonalat rajzol miközben figyeli a rajzolásra kijelölt terület határait. A program forráskódja: Code Segment assume CS:Code, DS:Data, SS:Stack Start: mov mov
ax, Code DS, AX
mov mov push
dl,100 dh,100 dx
;X_hossz kezdő érték ;Y_hossz kezdő érték ;X,Y koordináták verembe mentése
mov int
ax,13h 10h
;VGA módba váltás (320*200)
mov mov
ax,0a000h es,ax
; Videó memória kezdőcím ES-be
rajz: pop dx xor ah,ah mov al,dh push dx mov bx,320 mul bx pop dx add al,dl koordináta (CX) jnc pixel inc ah pixel: push dx mov di,ax mov al, 128 mov es:[di],al Var: mov
ah, 0
;X,Y koordinátákból számoljuk a pixelt ;pixel = Y koordináta (AX) * 320 (sor hossza) + X
; a kigyújtandó pixel színe
INT
16H
cmp jz
al,27 Program_Vege
cmp jz
ah,75 balra
cmp jz
ah,77 jobbra
cmp jz
ah,80 lefele
cmp jz
ah,72 felfele
jmp
var
pop dec cmp jnc inc
dx dl dl,1 tarol1 dl
; x,y koordináta kivétele a veremből ; Y_hossz (pixel)
push jmp
dx rajz
; x,y koordináta visszarakása a vereme
pop inc cmp jc dec
dx dl dl,250 tarol2 dl
; x,y koordináta kivétele a veremből ; Y_hossz (pixel)
push jmp
dx rajz
; x,y koordináta visszarakása a vereme
pop inc cmp jc dec
dx dh dh,200 tarol3 dh
; x,y koordináta kivétele a veremből ; Y_hossz (pixel)
push
dx
; x,y koordináta visszarakása a vereme
balra:
tarol1:
jobbra:
tarol2: lefele:
tarol3:
jmp
rajz
pop dec cmp jnc inc
dx dh dh,1 tarol4 dh
; x,y koordináta kivétele a veremből ; Y_hossz (pixel)
push push jmp
dx dx rajz
; x,y koordináta visszarakása a vereme ; x,y koordináta visszarakása a vereme
felfele:
tarol4:
Program_Vege: mov ax,3 int 10h pop
dx
mov int
ax, 4c00h 21h
Code Ends Data
Segment
Data
Ends
Stack Segment Stack Ends End Start
;szöveges módba váltás (80*25) ; verem ürítése