Content extract
Programozás II. KMAPR21TNB, KMAPR21ONB PC assembly Sándor Tamás Ajánlott irodalom • Diós Gábor és Rodek Lajos jegyzete. (http://wwwinfuszegedhu/~rusko/asm/jegyzetpdf) • Máté Eörs: Assembly programozás, Novadat, 2000. • Egyetemi Könyvtár • Magyar nyelvű programozás honlap • Pethő Ádám: Assembly alapismeretek Tartalom Assembly, assembler Assembly jelentősége, jellemzői Számrendszerek, gépi adatábrázolás I8086 processzor család Assembly szerkezete, szintaxisa Az i8086 processzor utasítás készlete Assembly programok készítése Vezérlési szerkezetek megvalósítása Turbo debugger használata BCD aritmetika, bitforgatás és léptetés Assembly és a magasszintű nyelvek kapcsolata Műveletek sztringekkel Az .EXE és COM programok, a PSP Szoftver megszakítások Hardver megszakítások, rezidens programok Assembly, assembler Assembly Gépi szintű programozási nyelv, közvetlenül a processzor utasítás készletét használja
Assembler Fordító program, amely az assembly programozási nyelven elkészített programot (.asm) tárgykódú programmá (.obj) fordítja Linker A tárgykódú programból futtatható fájlt (.exe) állít elő Mnemonikkal (mnemonic) Egy gépi utasítást helyettesítő 2-5 betűs kulcsszó. Assembly jelentősége, jellemzői nagyon egyszerű, elemi műveletek típustalanság rögzített utasításkészlet világos, egyszerű szintaxis kevés vezérlési szerkezet nagyon kevés adattípus; ha több is van, akkor általában egymásból származtathatók Assembly előnyei korlátlan hozzáférésünk van a teljes hardverhez, beleértve az összes perifériát (billentyűzet, nyomtató stb.) pontosan ellenőrizhetjük, hogy a gép tényleg azt teszi-e, amit elvárunk tőle ha szükséges, akkor minimalizálhatjuk a program méretét és/vagy sebességét is Assembly hátrányai a forrás sokszor áttekinthetetlen még a szerzőnek is a kódolás nagy figyelmet, türelmet, és
főleg időt igényel nagy a hibalehetőség a hardver alapos ismerete elengedhetetlen a forrás nem hordozható, azaz más alapokra épülő számítógépre átírás nélkül nem vihető át (ez persze igaz a gépi kódra is) Számrendszerek, gépi adatábrázolás 2, 8, 10, 16-os számrendszerben előjeles és előjelnélküli számokkal történő művelet végzés (+, -, *, /) BCD aritmetika 8086-os processzor jellemzői 8086-os felépítése Memóriakezelés Regiszterek Adattípusok Memória hivatkozások, címzési módok Veremkezelés I/O, megszakítási rendszer 8086 felépítése 8088 funkcionális blokkvázlata Memóriakezelés Memória- modellek A memória-modell a memória hozzáférésének módját és technikáját írja le. Fajtái: Lineáris modell Szegmentált modell Lapozásos modell Szegmentált memóriakezelés Fizikai cím = 10H* szegmens cím + ofszet cím Pl. 6A4B0H = 10H * 6A3BH + 0100H 00400H = 10H * 0030H + 0100H 00400H = 10H * 0020H + 0200H
Regiszterek Általános regiszterek AX (Accumulator) Aritmetikai utasítások bemeneti és eredmény értékét tárolhatja. BX (Base) Báziscímzés használt regiszter. CX (Counter) Ciklus utasítás esetén ciklusszámlálóként használatos. DX (Data) Port kezelő utasítások (In, Out) esetén a port címét tartalmazza. Általános regiszterek osztott hivatkozása AX 8. 7 15. AH 0. AL Vezérlő regiszterek SI (Source Index) – Blokk kezelő utasítások esetén a forrás terület címét tartalmazza. DI (Destination Index) Blokk kezelő utasítások esetén a cél terület címét tartalmazza. SP (Stack Pointer) A verembe legutóbb behelyezett érték címét tartalmazza. BP (Base Pointer) Báziscímzés esetén használatos, de alapesetben a verem egy elemét jelöli ki. Vezérlő regiszterek II. IP (Instruction Pointer) A következő végrehajtandó utasítás memóriacímét tartalmazza. Közvetlenül nem érhető el, de tartalma írható és olvasható is a
vezérlésátadó utasításokkal. SR avagy Flags (Status Register) A processzor aktuális állapotát, az előző művelet eredményét tartalmazza, illetve a processzor működését befolyásoló biteket, ú.n flag-eket (jelzőket) tartalmazza Szintén nem érhető el közvetlenül, de manipulálható különféle utasításokkal. Állapot regiszter (SR avagy Flags (Status Register) ) I. C (Carry) Előjel nélküli számábrázolás esetén művelet végzés után a számtartomány túllépését jelzi. O (Overflow) Előjeles számábrázolás esetén művelet végzés után a számtartomány túllépését jelzi. P (Parity even) 1, ha az eredmény legalsó bájtja páros számú 1-es bitet tartalmaz, különben 0. Állapot regiszter (SR avagy Flags (Status Register) ) II. A (Auxilliary carry, Adjust) 1 jelzi, ha volt átvitel az eredmény 3-as és 4-es bitje (tehát az alsó és a felső nibble) között. Pl. Adjuk össze a 78BCD és a 87BCD értékeket! 78BCD 87BCD 165BCD « «
0111 1000 +1000 0111 01111 1111 +0110 0110 BCD kiegészítés, A és a Cy bitek miatt 10110 0101 BCD aritmetika MOV AX,78h ; 78BCD-t hex formában adjuk meg ADD AX,87h ; 87BCD-t hex formában adjuk meg DAA ; BCD kiegészítést, ha szükséges, akkor elvégzi ; Carry és Ac állapotától függően Állapot regiszter (SR avagy Flags (Status Register) ) III. Z (Zero) Értéke 1, ha az eredmény zérus lett. S (Sign) Értéke 1, ha az eredmény nullánál kisebb lett. T (Trap) Ha 1, akkor a lépésenkénti végrehajtás (single-step execution) engedélyezve van. I (Interrupt enable) Ha 1, akkor a maszkolható megszakítások engedélyezettek. D (Direction) –Ha 0, akkor a blokk mozgató utasítások növelik SI-t és/vagy DI-t, különben csökkentés történik. Szegmens regiszterek CS (Code Segment) –A végrehajtandó program kódját tartalmazó szegmens címe. Nem állítható be közvetlenül, csak a vezérlésátadó utasítások módosíthatják. DS (Data Segment) –Az
alapértelmezett, elsődleges adatterület szegmensének címe. ES (Extra Segment) –Másodlagos adatszegmens címe. SS (Stack Segment) –A verem szegmensének címe. Címzési módok Program terület címzése Közeli cím JMP címke; ugrás szegmensen belül Távoli cím JMP FAR cím; ugrás szegmensen kívülre Relatív cím JE címke; ugrás előjeles egy bájtnyit Adatterület címzése Adatterület címzése Közvetlen címzés A címzés alakja [offs16], ahol offs16 egy 16 bites abszolút, szegmensen belüli ofszetet (rövid mutatót) jelöl. Pl. MOV AX, [3F4Bh] Báziscímzés A címzés egy bázisregisztert használ az ofszet cím megadására. A lehetséges alakok: [BX], [BP] A forrás adat ofszet címét a használt bázisregiszterből fogja venni a processzor. Pl. MOV CX, [BP] Indexcímzés A címzés egy index regisztert használ az ofszet cím megadására. Pl. MOV AX, [SI] Bázis+relatív címzés Ide a [BX+rel8], [BX+rel16], [BP+rel8], [BP+rel16] formájú
címmegadások tartoznak. A rel16 egy előjeles szó, rel8 pedig egy előjeles bájt, amit a processzor előjelesen kiterjeszt szóvá. Ezek az ú.n eltolások (displacement) Bármelyik változatnál a megcímzett bájt ofszetjét a bázisregiszter tartalmának és az előjeles eltolásnak az összege adja meg. Pl. MOV AX, [BP+07Ah] Index+relatív címzés Hasonlóan a báziscímzés / indexcímzés pároshoz, ez a bázis+relatív címzési mód párja. Alakjai: [SI+rel8], [SI+rel16], [DI+rel8], [DI+rel16]. Pl. MOV AX, [SI+06Bh] Bázis+index címzés A két nevezett címzési mód keveréke. A következő formákat öltheti: [BX+SI], [BX+DI], [BP+SI] és [BP+DI]. A regiszterek sorrendje természetesen közömbös, így [BP+SI] és [SI+BP] ugyanazt jelenti. A cél bájt ofszetjét a két regiszter értékének összegeként kapjuk meg Pl. MOV [SI+BP], AX Regiszter-regiszter címzés MOV AX, BX Stack terület címzése PUSH op. POP op. Stack (verem) Működése: Last In First
Out Alkalmazás: Szubrutinok visszatérési érték tárolása Paraméter átadás szubrutin híváskor Regiszterek ideiglenes tárolása Változók ideiglenes tárolása Utasítás: PUSH op. POP op. Veremkezelés példa mov mov mov push push pop push pop pop ax,1212h bx,3434h cx,5656h ax bx ax cx bx cx Kiindulási állapot SS:SP Memória cím tartalma hexában SS:0100H SS:00FEH SS:00FCH SS:00FAH AX=1212H, BX=3434H, CX=5656H, SP=0100H ? ? ? ? PUSH AX után SS:SP Memória cím tartalma hexában SS:0100H ? SS:00FEH 1212 SS:00FCH ? SS:00FAH ? AX=1212H, BX=3434H, CX=5656H, SP=00FEH PUSH BX után SS:SP Memória cím tartalma hexában SS:0100H ? SS:00FEH 1212 SS:00FCH 3434 SS:00FAH ? AX=1212H, BX=3434H, CX=5656H, SP=00FCH POP AX után SS:SP Memória cím tartalma hexában SS:0100H ? SS:00FEH 1212 SS:00FCH 3434 SS:00FAH ? AX=3434H, BX=3434H, CX=5656H, SP=00FEH PUSH CX után SS:SP Memória cím tartalma hexában SS:0100H ? SS:00FEH 1212 SS:00FCH 5656 SS:00FAH ? AX=3434H, BX=3434H,
CX=5656H, SP=00FCH POP BX után SS:SP Memória cím tartalma hexában SS:0100H ? SS:00FEH 1212 SS:00FCH 5656 SS:00FAH ? AX=3434H, BX=5656H, CX=5656H, SP=00FEH POP CX után SS:SP Memória cím tartalma hexában SS:0100H ? SS:00FEH 1212 SS:00FCH 5656 SS:00FAH ? AX=3434H, BX=5656H, CX=1212H, SP=0100H Assembly sor szerkezete, szintaxisa Szimbólum Műveleti kód Operandusz(ok) megjegyzés kiir: MOV AX, BX ; AX<-BX Szimbólum Direktíva Operandus ;megjegyzés SZAM EQU 5 ; konstans deklaráció http://asm.sourceforgenet/ Assembly nyelv elemei assembly utasítások (főleg ezek alkotják a tényleges program kódját) pszeudo utasítások (pl. makrók, helyettesítő szimbólumok) direktívák Assembly utasítások Operátorok Processzor utasításai Operátorok kerek zárójelek szokásos aritmetikai műveleti jelek (+, -, *, /, MOD) mezőkiválasztó operátor (.) szegmens-előírás / -felülbírálás (:) memóriahivatkozás ([. ]) típus felülbírálás (PTR)
adattípus megadás (BYTE, WORD, DWORD) duplikáló operátor (DUP) relációs operátorok (EQ, NE, GT, GE, LT, LE) pointer típusok (NEAR, FAR) szegmens /ofszet lekérdezés (SEG, OFFSET) méretlekérdező operátorok (LENGTH, SIZE, TYPE, WIDTH) Direktívák modul/forrásfájl lezárása (END) szegmens definiálása (SEGMENT . ENDS) szegmenscsoport definiálása (GROUP) szegmens hozzárendelése egy szegmensregiszterhez (ASSUME) értékadás a $ szimbólumnak (ORG) memória-modell megadása (MODEL) egyszerűsített szegmensdefiníciók (CODESEG, DATASEG, FARDATA,UDATASEG,UFARDATA, CONST, STACK, .CODE, DATA, STACK) helyfoglalás (változó létrehozása) (DB, DW, DD, DF, DQ, DT) Konstans / helyettesítő szimbólum létrehozása (=, EQU) címke létrehozása (LABEL) eljárás definiálása (PROC. ENDP) külső szimbólum definiálása (EXTRN) szimbólum láthatóvá tétele a külvilág számára (PUBLIC) feltételes fordítás előírása (IF, IFccc, ELSE, ELSEIF, ENDIF) külső
forrásfájl beszúrása az aktuális pozícióba (INCLUDE) felhasználói típus definiálása (TYPEDEF) struktúra, unió, rekord definiálása (STRUC. ENDS, UNION ENDS, RECORD) a számrendszer alapjának átállítása (RADIX) makródefiníció (MACRO. ENDM) makróműveletek (EXITM, IRP, IRPC, PURGE, REPT, WHILE) utasításkészlet meghatározása (P8086, P186, P286, P386 stb.; 8086, 186, 286, 386 stb) i8086 utasítás csoportjai Adatmozgató utasítások Blokk mozgató utasítások Aritmetikai és logikai utasítások Vezérlési szerkezetek Ugró utasítások Ciklus utasítások Szubrutinok Bitforgató, bitléptető utasítások Input, output utasítások Processzor vezérlő utasítások Megszakítás kezelő utasítások Adatmozgató utasítások MOV – adatok mozgatása XCHG– adatok cseréje PUSH– adat betétele a verembe PUSHF – Flags regiszter betétele a verembe POP – adat kivétele a veremből POPF – Flags regiszter kivétele a veremből LEA – tényleges
memóriacím betöltése LDS, LES – teljes pointer betöltése szegmensregiszter: általános regiszter regiszter párba CBW– AL előjeles kiterjesztése AX-be CWD– AX előjeles kiterjesztése DX:AX-be XLAT, XLATB– AL lefordítása a DS:BX című fordító táblázattal LAHF – Flags alsó bájtjának betöltése AH-ba SAHF – AH betöltése Flags alsó bájtjába Blokkmozgató utasítás MOVS, MOVSB, MOVSW– blokk mozgatása CMPS, CMPSB, CMPSW– blokkok összehasonlítása SCAS, SCASB, SCASW– keresés blokkban LODS, LODSB, LODSW– betöltés blokkból STOS, STOSB, STOSW– tárolás blokkba Példa a blokk másolásra Feladat: Másoljuk át 00100h forráscímtől kezdve 200h bájtot a 00200h címen kezdődő célterületre! forrásterület: 00100h002FFh célterület: 00200h003FFh STD MOV CX, 200H ; D bit beállítása ; ciklus számláló beállítása MOV MOV MOV MOV masol: MOVSB AX, DS ; ES, AX ;ES <- DS DI, 3FFH ; cél ofszet cím SI, 2FFH ; forrás ofszet
cím ;ES:[DI] <- DS:[SI] LOOP masol ; CX=CX-1 addig, CX>0 Vezérlési szerkezetek I. JMP – feltétel nélküli ugrás JCXZ – ugrás, ha CX = 0000h Jccc – feltételes ugrás („ccc” egy feltételt ír le) CMP op1, op2; op2-op1 Reláció Műveleti kód S (előjelbit) Z (zéró bit) op1 > op2 JA 1 0 op1 < op2 JB 0 0 op1 = op2 JE 0 1 ;amíg Ciklus utasítás LOOP címke Pl. masol: MOVSB LOOP masol ; CX=CX-1 addig, ;amíg CX>0 CX=végrehajtási szám Ciklustörzs CX=CX-1 i CX>0 h Feltételes ciklusok LOOPE címke LOOPZ címke masol: MOVSB LOOPZ masol ; CX=CX-1 addig, ZF = 1 LOOPNE címke LOOPNZ címke ;amíg CX>0 és Szubrutinok CALL – eljárás (szubrutin) hívása RET, RETF – visszatérés szubrutinból Szubrutin híváskor az IP értéke elmentődik mov call mov . . . . . . szamol proc mov mov add ret szamol endp ax, bx szamol; cx, dx SS:[SP] <- IP A szubrutinból való visszatérés után a következő
utasítással folytatódik a program ax, 3 bx, 2 ax,bx ; IP <- SS:[SP] Szubrutin befejezésekor az IP értéke visszaállítódik Input, output utasítások IN al, dx IN ax, dx dx: port cím OUT dx, al OUT dx, ax dx: port cím Megszakítások INT megszakítási szám Pl. INT 21H INTO– INT 04h hívása, ha OF = 1, különben NOP-nak felel meg IRET – visszatérés megszakításból Egész számos aritmetika ADD– összeadás ADC– összeadás átvitellel (CF) együtt SUB – kivonás SBB – kivonás átvitellel (CF) együtt CMP – összehasonlítás (flag-ek beállítása a cél és a forrás különbségének megfelelően) INC– inkrementálás (növelés 1-gyel), CF nem változik DEC– dekrementálás (csökkentés 1-gyel), CF nem változik NEG– kettes komplemens képzés (szorzás −1-gyel) MUL – előjeltelen szorzás IMUL – előjeles szorzás DIV – előjeltelen maradékos osztás IDIV – előjeles maradékos osztás Összeadás Pl. Adjuk össze a 3F4Bh
és 4141h értéket! MOV AX, 3F4Bh MOV BX, 4141h ADD AX, BX ;AX<- AX+BX Pl. Végezzük el az alábbi műveletet! « 4C22 9A4Dh + 3D33 8B3Ah 7F56 2587h MOV MOV ADD MOV MOV ADC AX, 9A4Dh BX, 8B3Ah AX, BX CX, 4C22h DX, 3D33h CX, DX Logikai utasítások AND op1, op2 Pl. Maszkolás & ;AX<-AX+BX ;CX<-CX+DX+Cy ;op1<-op1&op2 0011 1111 0100 1011 0000 0000 0100 0000 0000 0000 0100 0000 MOV AX, 3F4Bh AND AX, 0040h OR op1, op2 Pl. Maszkolás + ;op1<-op1+op2 0011 1111 0100 1011 1111 1111 1011 1111 1111 1111 1111 1111 MOV AX, 3F4Bh OR AX, FFBFh XOR op1, op2 Pl. ; op1 <- op1⊕op2 MOV AX,0 XOR AX,AX NOT egyes komplemens képzés TEST logikai bit tesztelés Pl. MOV AX, 3F4Bh TEST AX, 0040h ; S és Z bit állítása Bitléptető utasítások SHL – előjeltelen léptetés (shiftelés) balra SHL Pl. op, 1/CL MOV CL, 3 MOV AX, 2 SHL AX, CL ;AX<- 2*22 SAL – előjeles léptetés balra (ugyanaz, mint SHL) SHR– előjeltelen léptetés jobbra SHR
Pl. op, 1/CL MOV CL, 3 MOV AX, 8 SHR AX, CL ;AX<- 8/2/2/2 SAR– előjeles (aritmetikai) léptetés jobbra SAR Pl. op, 1/CL MOV CL, 3 MOV AX, F8h SAR AX, CL ROL – balra forgatás (rotálás) ;AX <- -8/2/2/2 ROL op, 1/CL Pl. MOV CL, 3 MOV AX, 8h ROL AX, CL RCL balra forgatás Carry Flag-en át RCL op, 1/CL ROR – jobbra forgatás ROR op, 1/CL RCR– jobbra forgatás CF-en át RCR op, 1/CL Processzor vezérlő utasítások CLC–CF flag törlése CMC–CF flag komplementálása (invertálása) STC–CF flag beállítása CLD–DF flag törlése STD–DF flag beállítása CLI – IF flag törlése STI – IF flag beállítása Assembly programok készítése TASM {opciók} forrás{,tárgykód}{,lista}{,xref} /a, /s A szegmensek szerkesztési sorrendjét befolyásolják. Az első ábécé rend szerint, míg a második a definiálás sorrendje szerinti szegmens-sorrendet ír elő. Alapértelmezés a /s /l, /la A listázás formátumát befolyásolják:
normál (opció/l) ill. kibővített (/la) lista fog készülni Alapértelmezésben nem készül lista. /m# A fordítás # menetes lesz (a „#” helyére egy számot kell írni). Alapérték a 2 /z Hiba esetén a forrás megfelelő sorát is kiírja. /zi, /zd, /zn A tárgykódba bekerülő nyomkövetési információt befolyásolják: teljes (/zi), csak a programsorok címei (/zd) vagy semmi (/zn). Alapértelmezés a /zn Linkelés TLINK {opciók} tárgykód fájlok{, futtatható fájl}{, térkép}{, könyvtárak} /x, /m, /l, /s A térkép (map) tartalmát befolyásolják: nincs térkép (/x), publikus szimbólumok listája lesz (/m), kódhoz tartozó sorszámok lesznek (/l), szegmensinformáció lesz (/s). Alapértelmezés a /s. /c Érzékeny lesz a kisbetűkre és nagybetűkre. /v – Engedélyezi a nyomkövetési információk beépítését a futtatható fájlba. /t –Az alapértelmezett .EXE helyett COM típusú futtatható fájlt készít Fordítás menete outint proc push push
push push ;soremeles mov mov int mov mov int mov mov mov ax bx cx dx dl,13d ah,2 21h dl,10d ah,2 21h ax,szam bx,10 cx,0 oszt: xor div push inc cmp ja dx,dx bx dx cx ax,0 oszt pop dx kiir: vege1: pop outint add mov int loop dx pop pop pop ret endp dx,0 ah,2 21h kiir cx bx ax Programfordítás Fordítás lépései: Fordításhoz használható batch fájl: tasm /zd /la %1.asm tlink /v %1.obj Turbo debugger használata Assembly és a magas szintű nyelvek kapcsolata C forrás: extern "C" { extern unsigned int szamol(char ,char, char); } ASM forrás: PUBLIC szamol Példaprogram I. #include <stdio.h> char a=3, b=4, c=5; extern "C" { extern unsigned int szamol(char ,char, char); } void main(void) { unsigned int eredmeny; eredmeny = szamol(a, b, c); printf("Eredmény: %d ", eredmeny); } DOSSEG .MODEL SMALL .CODE PUBLIC szamol szamol PROC push bp mov bp,sp xor mov add adc ax,ax al,BYTE PTR [bp+4] al,BYTE PTR [bp+6] al,BYTE PTR [bp+8]
pop bp ret szamol ENDP END Példaprogram II. #include <stdio.h> char * TestString="Line 1 line 2 line 3"; extern "C" { extern unsigned int LineCount(char * StringToCount, unsigned int * CharacterCountPtr); } main() { unsigned int LCount; unsigned int CCount; LCount = LineCount(TestString, &CCount); printf("Lines: %d Characters: %d ", LCount, CCount); } NEWLINE EQU 0ah DOSSEG .MODEL SMALL .CODE PUBLIC LineCount LineCount PROC push bp mov bp,sp ;the linefeed character is Cs newline character push si ;preserve calling programs register variable, if any mov si,[bp+4] ;point SI to the string sub cx,cx ;set character count to 0 mov dx,cx ;set line count to 0 LineCountLoop: lodsb ;get the next character and al,al ;is it null, to end the string? jz EndLineCount ;yes, were done inc cx ;no, count another character cmp al,NEWLINE ;is it a newline? jnz LineCountLoop ;no, check the next character inc dx ;yes, count another line jmp LineCountLoop
EndLineCount: inc dx ;count the line that ends with the null character mov bx,[bp+6] ;point to the location at which to return the character count mov [bx],cx ;set the character count variable mov ax,dx ;return line count as function value pop si ;restore calling programs register variable, if any pop bp ret LineCount ENDP END Az .EXE és COM programok, a PSP comprog.asm exeprog.asm Szoftver megszakítások 10h FFh Jellegzetes szoftveres megszakítások Hardver megszakítások 0 Fh Megszakítás vezérlő Megszakítás fogalma Megszakítás kiszolgálás lépései Megszakításkérés hatására a futó program felfüggesztődik (CS:IP értéke és a Flags regiszter elmentődik) Megszakításkérés elbírálásra kerül (Flags regiszter Interrupt bit) Ha engedélyezett a megszakításkérés kiszolgálása, akkor a megszakítás vektortáblából (0:mszam*4) a kiszolgáló rutin címe betöltődik Kiszolgáló rutin lefut (IRET) CS:IP érték visszatöltődik A felfüggesztett
program futása folytatódik a következő utasítással