ASSEMBLY GYAKORLAT 1. Irta Kaproncai Tamas [tomcat@szif.hu] -ADATMOZGATAS- Assembler Assembly --------------> Gepi kod Assembly Programozasi nyelv, a gep nyelvenek egy emberi formaja. Gepi kod A gep nyelve, gep szamara ertelmezheto kodsorozat. Assembler Fordito program, ami a assembly forras nyelvu programbol keszit gepi kodot. Gyakorlatban: P.ASM -----NASM-----> P.COM \ VAL -----> P.OBJ ==========> P.EXE P.ASM - egy szovegfajl NASM - free assembler (szabad terjesztesu fordito) P.COM - binaris kodsorozat P.OBJ - binaris kodsorozat + jarulekos informaciok (pl. valtozo nevek) P.EXE - tobb objekt fajlbol szerkesztett futtathato fajl VAL - free linker (szabad terjesztesu szerkeszto) (Mi kezdetben, az egyszeruseg kedveert csak COM programokat irunk). 1a. Irjuk meg az elso programunk, amiben csak egy db sor van: RETN Ehhez barmilyen szovegszerkesztot hasznalhatunk. Ez lehet az NC vagy a DN beepitett szovegszerkesztoje, vagy a Pascal keretrendszere, vagy a sima DOSEDIT. A lenyeg, hogy - a szerkesztot alaposan ismerd - legyen szamodra kenyelemes - lehetoleg tudj a programod tobb verziojaval dolgozni egyszerre - es a kulonbozo verziok osszehasonlithatok legyenek (hibakereses) En is hoztam egy szovegszerkesztot, amely azon tul, hogy megfelel az elvarasoknak, rendelkezik meg egy elonnyel: csupan 32kB. NE.COM (Norton Editor 1.3B) - Kilepni belole F3+E billentyuvel lehet, aki tobbre is kivancsi: F1 1b. Forditsuk le ezt az elso programot! Inditsuk el a forditot: NASM Megegyszer: NASM -h Harmadszor: NASM P.ASM Mi tortent? A programunk azert nem kapott automatikusan COM kiterjesztest, mert ez az assembler nem csak DOS kornyezetben mukodik (netwide). Negyedszer: NASM P.ASM -oP.COM Most mar futtathato a program - nem torteneik semmi kulonos, visszalep a DOS-hoz. Mekkora a COM program hossza? (1 bajt) Ha valaki megnezi hex.editorral, akkor lathatja, hogy ennek az 1 bajtnak 0C3H az erteke. Vagyis a RETN assembly utasitas gepi kodban 0C3H. 1c. Irjuk egy batch fajlt, amivel konyebben fordithatunk! C.BAT @nasm %1.asm -o%1.com -w+orphan-labels %2 %3 if errorlevel 1 goto vege @cls @%1 :vege Nemcsak fordit ez a batch fajl, hanem futtat is, de csak akkor ha hibatlan volt a forditas, es a futtatas elott letorli a kepernyot. A -w+... opcio szigorubb ellenorzest kapcsol be a forditaskor. Probaljuk ki a C.BAT fajlunk (de elotte toroljuk le a P.COM fajlt)! 2a. Irjuk meg masodik programunk! Megismerjuk az elso es legalapvetobb utasitast, az adatmozgatast. Az utasitas neve MOV es ket operandusa van, pl.: MOV AX, 0 cel op. <--adat-- forras op. (AX) (0) Az AX 16 bites regiszter erteke 0 lesz. MOV ES,AX ES szegmens regiszter erteke AX regiszter erteket kapja meg, azaz nullat. Ezeket az utasitasokat a RETN utasitasunk ele gepeljuk be! A programot oszlopokba irjuk, egy sorba csak egy utasitas kerul. Az elso oszlopot kihagyjuk a cimkeknek, a 2. oszlopba az utasitasokat, a 3. oszlopba az operandusokat, a 4. oszlopba pedig a megjegyzeseket irhatjuk. Figyelem: Minden olyan sort nem ertelmez tovabb a fordito, amiben egy pontosvesszot talal. A ; jel utan irhatjuk a megjegyzeseinket. Meg egy utasitasunk lesz: MOV [ES:417H],BYTE 70H - A szamok utan a H betu hexadecimalis (16-os szamrendszerbeli) szamot jelent. - [] zarojel a memoria valtozokat, memoria cimzeseket fogja keretbe. - A : jel a cimzes szegmes-offset reszet kapcsolja ossze. - A BYTE kulcsszo utal arra, hogy csak 1 bajot irunk a memoriaba Forditsuk le es futtasuk a programunk! Mi tortent? - A memorianak egy olyan erteket irtuk at, ami a ledek allapotaert felelos. Nezzuk meg melyik is ez a fizikai memoriacim... Szegmens-offset cimzes ---------------------- Lathato egy db 16 bites regiszter nem lesz eleg a teljes memoria cimzesehez. Ket darab 16 bites regiszterrel akar 4GB memoriat is cimezhetnenk, de az XT-k idejen csak 1MB memoria letezett. Ehhez 20 bit kell, ezert a szegmens-offset regiszterek 4 bittel eltolva adodnak ossze. Ez azt jelenti, hogy egy cimet tobb fele modon is felirhatunk. Ha pl. a szegmens regisztert noveljuk eggyel, az ugyanaz, mint ha az offsetet noveltuk volna 16-tal. A hexa szamoknal a 4 bites eltolas pont egy jegyet jelent: 0000H 0040H 0041H 0021H + 0417H + 0017H + 0007H + 0207H ------- ------- ------- ------- 00417H 00417H 00417H 00417H 2b. Miutan a billentyuzeten visszakapcsoltuk a ledeket, probaljuk ki a programunkat masik szegmens-offset parral is! Gyozodjunk meg rola, hogy igy is kigyulladnak a ledek, vagyis ugyanarra a memoriacimre irtunk, ahova az elobb! A kesobbiekben mindig, mielott egy ujabb feladatba kezdenenk mentsuk el uj neven a programunkat es utana nyugodtan modosithatjuk a P.ASM fajlt. Pl. COPY P.ASM P1.ASM 3a. Feladat jelenitsunk meg egy A betut a kepernyo kozepen! A feladat ugyanolyan, mint az elobb csak tudnom kell, hogy a memoria mely pontjara es mit kell mozgatnom (az A betu ASCII kodjat). - benne lehetoseg onallo munkara... Megoldas: B80000H fizikai cimen van a keprnyo memoria terulete. Tehat MOV ES,0B800H ; a bevezeto 0 kell, ha betu az elso jegy! Igy a 0-s offset a kepernyo bal-felso karakterere fog mutatni: =======> ---------- A karakterek pedig sorfolytonosan vannak |123... | letarolva. |... | | | ---------- Szamoljuk ki a kepernyo kozepenek a memoria cimet! Egy karakterhez hany bajt tartozik? - ketto: egy ASCII kod es egy attributum ertek Egy sorhoz hany bajt tartozik? - 80 karakter -> 160 bajt A kepernyo kozepenek cime: - 12 sor meg egy fel sor -> 12*160+80 Mi az A betu ASCII kodja? - TECHHELP (ld. meg THELP -> ROM-BIOS Data Area -> 0:0417H) MOV [ES:12*160+80],BYTE 'A' Ha nem szamoljuk ki a kifejezest, akkor igy sokkal szemleletesebb es kesobb konnyebben modosithato. 3b. Legyen az A betu kek alapon feher szinu! MOV [ES:12*160+81],BYTE 17H THELP -> Screen Attributes 3c. Foglaljuk egybe a ket utasitast! WORD eseten a kisebbik helyierteku bajt erteke kerul az alacsonyabb cimre, a nagyobb helyierteku bajt erteket pedig a memoria kovetkezo bajtja veszi fel. MOV [ES:12*160+80],WORD 1700H + 'A' Kilepes elott varjunk egy billentyu leutesere: MOV AH,0 INT 16H Az INT utasitassal megszolitjuk a BIOS billentyuzet kezelo reszet (16H). O pedig az AH ertekebol tudja, hogy mit kell tennie. THELP -> ROM-BIOS Functions -> INT 16H 4a. A grafikus kepernyo kozepen jelenitsunk meg egy feher pontot. Most be kell kapcsolni a grafikus uzemmodot (320x200x256 szin), ami a billetyzet kezelesehez hasonloan INT utasitassal tortenik, csak most a kepernyokezelo reszt szolitjuk meg (10H). MOV AH,0 MOV AL,13H INT 10H AH regiszter AX felso bajtja, AL regiszter pedig AX also bajtja, igy a ket utasitast egybe is foglalhatjuk: MOV AX,13H INT 10H THELP -> ROM-BIOS FUnctions -> INT 10H -> Video Service Detail Kilepes elott illik visszakapcsolni a karakteres kepernyot, ha csak nem vakon szeretnenk gepelni a tovabbiakban. MOV AX,3 INT 10H Akkor a szokasos modon - a keprnyo szegmens cime: A000H - a 256 szin suggalja, hogy 1 pixelhez (kepponthoz) 1 bajt tartozik - 1 sorhoz igy 320 bajt kell - tehat a megfelelo cim: 100*320+160 A kiirando ertek egy sorszam lesz a szinpalettarol. Az alap paletta 15. szine feher. MOV [ES:100*320+160],BYTE 15 4b. A ora hatralevo reszeben mindenki adjon maganak onallo feladatot, pl. a kepernyo 4 sarkaba is irjon ki mas-mas szinu pontokat. Osszefogalalaskent, mikozben dolgoztok, ennyi kostolo utan beszeljuk meg, hogy milyen elonyei is milyen hatranyai vannak az Assembly nyelvenek egy magasabb szintu nyelvhez (pl. Pascalhoz) kepest! + a leforditott kodba pontosan az kerul bele, amit a programozo szeretett volna + ezert a kod altalaban joval rovidebb es gyorsabb + ha megtanultad, hasznalhatod minden magsabb szintu nyelveben is + a nyelv nem szab korlatokat, mert nincsenek adott 'epitokockak' - legeloszor nullarol kell kezdenunk a programozast -> nehezkes - szukseges a hardver es a rendszer melyebb, alaposabb isemerete.