Bevezetés Assebly feladatok 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 NOT NEG AND XOR JMP JZ JNZ JC JNC CALL RET 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. ( 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 dec monik utasításkód adat (operandus) megjegyzés B4 02 ah, 2 B2 41 dl, 41h ; A CD 21 int 21 h CD 20 int 20 h A tagolás általános formája: ah,2 dl,41h ; A int 20h
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: Kiir: ax, Code DS, AX ah, 02h bh, 0 dh, 10 ;Cursor a 10. sorra dl, 0 ;Cursor a 0. oszlora int 10h Kurzor pozícionálás Üzenet1 kiírás Üzenet2 kiírás dx, offset uzenet1 ;Uzenet1 kiirasa ah, 09 dx, offset szamlalo ;szamlalo kiirasa ah, 09 dx, offset uzenet2 ;Uzenet2 kiirasa ah, 09 Üzenet3 kiírás Bevitel ESC a Program vége Számláló növelésel
Bevitel: xor ax,ax int 16h ;Varakozas egy billentyu leutesre Vizsg: ah,27 ;Kilepes gombja cmp ah,al jz Program_Vege ah,'a' cmp jz jmp ah,al Szamol Bevitel Szamol: inc jmp di,offset szamlalo al, [di] al [di], al Kiir Program_Vege: ax, 4c00h uzenet1: db "Az A billentyu $" uzenet2: db " alkalommal volt leutve$" szamlalo: db "0$" Code Ends Data Data Segment 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: int ax,progi ds,ax di,offset ertek ax,03 ;Keprenyo torles 10h Bevitel: xor ax,ax int 16h ;Varakozas egy billentyu leutesre bx,ax ;ax elmentese bx-be ax,03 int 10h ;Kepernyo torles ax,bx ;ax visszaallitasa ah,27 ;Kilepes gombja cmp ah,al jz Kilep
cx,10 ;Ennyiszer fut a VIZSG rutin ah,'0' Vizsg: cmp ah,al ;Itt vegignezzuk 0-9-ig, hogy a bevitt karakter szam-e jz Tarol ;Ugrunk, ha szam inc ah loop Vizsg ah,02h ;Itt megyunk tovabb, ha szam bh,0 dh,10 ;Cursor a 10. sorra dl,0 ;Cursor a 0. oszlora int 10h dx,offset Hiba ;Hibauzenet kiirasa ah,09 jmp Bevitel Tarol: [di],al ;Az ERTEK memoriahelyre letesszuk a bevitt szamot inc di ;Itt meg ASC kodban van a szam al,'$' ;String lezaro karakter [di],al ;Most kerult a sztring vegere a dollar jel ah,02h bh,0 dh,05 ;Cursor a 5. sorra dl,28 ;Cursor a 28. oszlora int 10h dx,offset ertek ah,09 ;Az eddig begepelt szamok kiirasa ax, offset ertek add ax,04 ;Ha a begepelt szam 4 helyerteku, akkor bevitel vege bx,di sub ax,bx jnz Bevitel ;Meg nincs meg a negy, mert AX+4 nagyobb mint DI
Kilep: ah,02h bh,0 dh,07 ;Cursor a 7. sorra dl,0 ;Cursor a 0. oszlora int 10h dx,offset uzenet ;Bevitel vege ah,09 int Progi ENDS ax,4c00h 21h Hiba db 'Nem megengedett karakter!$' ertek db '*****$' uzenet db 'Vege a bevitelnek$' Stack segment Stack ENDS END START Start Képernyő törlés Bevitel Képernyő törlés ESC 0-9 Kurzor pozícionálás Hiba kiírás Program vége Tárolás Kurzor pozícionálás Hiba kiírás Szám hossza 4
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 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ó á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 Képerny törlés Kurzor pozícionálás Poz < 5 Poz < 10 T := 16 T := 8 Labda kirakás Poz < 15 T := 4 Billenty figyelés ESC Program vége Poz < 20 T := 1 T := 2 Óra beolvasás Eltelt id:= T-T-1 T > T T -1 := T Poz = 0 SI := 1 Poz = 0 SI := -1 Képerny törlés Poz := Poz + SI
Code Segment assume CS:Code, DS:Data, SS:Stack Start: 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 Torles: MOV DX, DI MOV DH, DL ;Karakteres videomod be (itt kepernyo torles) ;Kepernyopozicionalas DI sorra es 40. karakterre ;Azert kell, mert DH-ba kell DI also MOV DL, 40 XOR BH, BH MOV AH, 2 INT 10H MOV DX, offset Labda MOV AH, 9 INT 21H ;Labda kirakas Kesleltet: MOV AH,01 int 16h ;Varakozas egy billentyu leutesre jnz Program_Vege XOR AH, AH INT 1Ah ;Ora beolvasasa CX:DX -be POP CX ;Regi ido kivetele a verembol PUSH CX ;Regi ido vissza a verembe MOV AX, DX ;Aktualis ido elmentese AX-be SUB DX, CX ;DX-BE IDO-REGI_IDO (eltelt ido)
PUSH AX ;AX elmentese CMP DI, 5 ;Ha a labda y=0-5 JNC Ido1 MOV AL,16 ;Sebessege 1/16 JMP Beallit Ido1: Ido2: Ido3: Ido4: CMP DI, 10 ;Ha a labda y=6-10 JNC Ido2 MOV AL,8 ;Sebessege 1/8 JMP Beallit CMP DI, 15 ;Ha a labda y=11-15 JNC Ido3 MOV AL,4 ;Sebessege 1/4 JMP Beallit CMP DI, 20 ;Ha a labda y=16-20 JNC Ido4 MOV AL,2 ;Sebessege 1/4 JMP Beallit MOV AL,1 ;Sebessege 1 Beallit: XOR AH, AH CMP DX, AX ;Az ido beallitasa (AL*1/18sec) POP AX ;AX visszaallitasa JC Kesleltet POP CX ;Regi ido kivetele a verembol PUSH AX ;Aktualis ido elmentese CMP DI, 0 JZ Le CMP DI, 25 JZ Fel ;Ha a labda fenn van ;Ha a labda lenn van
Mozgas: MOV DX, DI MOV DH, DL ;Kepernyopozicionalas DI sorra es 40. karakterre ;Azert kell, mert DH-ba kell DI also MOV DL, 40 XOR BH, BH MOV AH, 2 INT 10H Le: FeL: MOV DX, offset Ures MOV AH, 9 INT 21H ADD DI, SI JMP Torles MOV SI, 1 JMP Mozgas MOV SI, -1 JMP Mozgas ;Labda torlese ;A labda uj pozicioja ;A mozgas iranya 1=lefele ;A mozgas iranya -1=felfele Program_Vege: POP CX ;Verem uritese ax, 4c00h Labda db "O$" Ures db " $" Code Ends Data Data Segment Ends Stack Segment Stack Ends End Start
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: s y =1/2g*t 2, s x =v x *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 DL, [DI] CMP DL, "/" JZ ParamKezdet INC DI LOOP Keres JMP Default ParamKezdet: INC DI MOV BL, [DI] ;Elso szamjegy (*10) SUB BL, 48 INC DI MOV BH, [DI] ;Masodik szamjegy (*1) SUB BH, 48 MOV AX, 10
MUL BL ADD AL, BH MOV CX, AX JMP Init Default: MOV CX, 10 ;AL-ben a szam ;Alapertelmezett V0 Init: 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) Rajz: MOV BX, DI MOV DH, BL MOV BX, SI MOV DL, BL XOR BH, BH MOV AH, 2 INT 10H ;Kepernyopozicionalas DI sorra ;Azert kell, mert DH-ba kell DI also ;Kepernyopozicionalas SI karakterre ;Azert kell, mert DH-ba kell DI also MOV DX, offset Labda MOV AH, 9 INT 21H ;Golyo kirakas POP AX ;Ido kivetele PUSH AX ;Ido elmentese MOV BL, AL ;A szorzashoz BL toltodik AL-el MUL BL ;Eredmeny AX-ben SHR AX, 1 ;2-vel osztunk MOV DI, AX ;Beirjuk az uj Y koordinatat POP AX ;Ido kivetele INC AX ;Ido novelese
PUSH AX ;Ido elmentese DEC AX ;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 SI, 80 JNC Var CMP DI, 25 JNC Var JMP Rajz Var: XOR AX, AX INT 16H Program_Vege: POP CX ;Verem uritese ax, 4c00h Labda db "O$" Code Ends Data Data Segment 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: ax, Code DS, AX dh, 10 ;Y koordinata dl, 20 ;X koordinata ah, -1 ;y iranya al, -1 ;X iranya push ax push dx Main: ;***************************************************************** ; A karater torlese ah, 02h bh, 0 pop dx ;DL:X koordinata ;DH:Y koordinata push dx int 10h dx, offset ures ; Space kiirasa ah, 09 ;***************************************************************** pop dx ;DL:X koordinata ;DH:Y koordinata pop ax ;AH:X iranya ;AL:Y iranya ;***************************************************************** ; A szelso ertekek megadasa bh, 64 bl, 1
ch, 24 cl, 1 ;***************************************************************** add dl, al cmp dl, bh jnz tovabb1 al, -1 tovabb1: cmp dl, bl jnz tovabb2 al, 1 tovabb2: add dh, ah cmp dh, ch jnz tovabb3 ah, -1 tovabb3: cmp dh, cl jnz tovabb4 ah, 1 tovabb4: push push ax dx ;***************************************************************** ; A karakter kirakasa ah, 02h bh, 0 pop dx ;DL:X koordinata ;DH:Y koordinata push dx int 10h dx, offset jel ; O kiirasa ah, 09 ;***************************************************************** xor ax,ax int 16h ;Varakozas egy billentyu leutesre ah,27 ;Kilepes gombja cmp ah,al jz Program_Vege
jmp Main Program_Vege: ax, 4c00h ures: db " $" jel: db "0$" Code Ends Data Data Segment 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: ax, Code DS, AX dl,100 ;X_hossz kezdő érték dh,100 ;Y_hossz kezdő érték push dx ;X,Y koordináták verembe mentése ax,13h int 10h ;VGA módba váltás (320*200) ax,0a000h ; Videó memória kezdőcím ES-be es,ax rajz: pop dx xor ah,ah al,dh push dx bx,320 mul bx ;X,Y koordinátákból számoljuk a pixelt pop dx add al,dl ;pixel = Y koordináta (AX) * 320 (sor hossza) + X koordináta (CX) jnc pixel inc ah pixel: push dx di,ax al, 128 ; a kigyújtandó pixel színe es:[di],al Var: ah, 0
INT 16H cmp jz cmp jz cmp jz cmp jz cmp jz jmp al,27 Program_Vege ah,75 balra ah,77 jobbra ah,80 lefele ah,72 felfele var balra: pop dx ; x,y koordináta kivétele a veremből dec dl ; Y_hossz (pixel) cmp dl,1 jnc tarol1 inc dl tarol1: push dx ; x,y koordináta visszarakása a vereme jmp rajz jobbra: pop dx ; x,y koordináta kivétele a veremből inc dl ; Y_hossz (pixel) cmp dl,250 jc tarol2 dec dl tarol2: push dx ; x,y koordináta visszarakása a vereme jmp rajz lefele: pop dx ; x,y koordináta kivétele a veremből inc dh ; Y_hossz (pixel) cmp dh,200 jc tarol3 dec dh tarol3: push dx ; x,y koordináta visszarakása a vereme
jmp rajz felfele: pop dx ; x,y koordináta kivétele a veremből dec dh ; Y_hossz (pixel) cmp dh,1 jnc tarol4 inc dh tarol4: push dx ; x,y koordináta visszarakása a vereme push dx ; x,y koordináta visszarakása a vereme jmp rajz Program_Vege: ax,3 int 10h ;szöveges módba váltás (80*25) pop dx ; verem ürítése int ax, 4c00h 21h Code Ends Data Data Segment Ends Stack Segment Stack Ends End Start