Névjegyzék

Bevezetés az összeszerelő nyelvhez. A V86 mód különleges helyzetei

Összeszerelők MASM, a TASM és a WASM különböznek egymástól. Azonban az egyszerű programok létrehozása gyakorlatilag nem rendelkezik különbséggel, kivéve a Közgyűlés és az elrendezés kivételével.

Tehát az első programunk a MASM, a TASM és a WASM számára, amely az aktuális kurzor helyzetben az "A" angol betűt mutatja, azaz a bal oldalon felső sarok Képernyő:

Model Tiny .Code Org 100h Start: MOV AH, 2 MOV DL, 41HT INT 21HT INT 20H VÉGE START Ez a szöveg bármilyen egyszerűen beírható szöveg szerkesztő - Például a Notepad ablakokból (de nem szóban, és nem egy másik "trükkös"). Azonban javaslom a "fejlett" szövegszerkesztőt egy szintaxis megvilágítással, például a PSPAD (lásd a szakaszt). Ezután mentse ezt a fájlt kiterjesztéssel, például a MyPROG mappában. Hívjuk az artest fájlt. Szóval: C: C: MyProg \\ atest.asm.

JEGYZET
Kérjük, vegye figyelembe, hogy az első csapatban a 02h helyett 2-et rögzítettünk. MASM TASM és WASM, mint EMU8086, elismerem, mint "szabadság". Bár 02h-t írhatsz - nem lesz hiba.

A program magyarázata:

.Model apró - 1. sor. Az irányelv.model meghatározza a memória modellt egy adott fájl típusához. A mi esetünkben ez egy COM kiterjesztésű fájl, ezért kiválasztjuk az apró modellt, amelyben a kód, az adatok és a verem szegmensei kombinálhatók. Az apró modellt úgy tervezték, hogy SOM típusú fájlokat hozzon létre.

.kód. - 2. sor. Ez az irányelv a kódszegmens megkezdi.

ORG 100H. - 3. karakterlánc. Ez a parancs beállítja a szoftverszámláló értékét 100 órán belül, mert amikor a SOM fájl memóriában történő betöltésekor az első 256 bájtot választja az első 256 bájt PSP adatblokkra (a 256 decimális számot, amely a hexadecimális 100H-nak felel meg). A programkód csak a blokk után található. A COM-fájlokba összeállított programoknak meg kell kezdeniük ezt az irányelvet.

start: Mov ah, 02h - 4. sor. A Start Label az első parancs előtt található, és a végső irányelvben fogja használni, hogy meghatározza, melyik parancs megkezdi a programot. A MOV utasítás az első operandumban a második operandum értékét helyezi el. Ez az, hogy a 02h érték az EN-regiszterbe kerül. Mit csinált? A 02h egy Dosova funkció, amely szimbólumot jelenít meg a képernyőn. Egy programot írunk a DOS számára, így használjuk a parancsokat operációs rendszer (OS). És ezt a funkciót (vagy inkább a számát) írjuk, az EN-nyilvántartásban van, mert a 21h megszakítás ezt a különleges regisztert használja.

MOV DL, 41H - 5. sor. Az "A" szimbólumkódot a DL regiszterbe írja be. Az "A" kód az ASCII szabvány szerint a 41h.

INT 21H. - 6. sor. Ez a legnagyobb megszakítás 21h - egy parancs, amely az EN-regiszterben megadott DOS rendszerfunkciót okozza (példánkban egy 02h funkció). Az INT 21H parancs az operációs rendszerek programjainak interakciójának fő eszköze.

INT 20H. - 7. sor. Ez a megszakítás, amely az operációs rendszert a programból származó kimenetről és a menedzsment átadásáról jelent meg konzol alkalmazás. Abban az esetben, ha a program már összeállítja és fut az OS-ből, az INT 20H parancs visszatér bennünket az OS-hez (például DOS-ban).

Vége - 8. sor. A végső irányelv ugyanakkor befejezi a programot, jelezve, hogy melyik címkét kell végrehajtani.

INT 3.

Hívás megszakítása 3 (#bp, stoppount)

8086

iNT 3.

CD ib.

Int. immétum.

Megszakítja a megszakításokat immétum.

8086

iNT 13.

Ba

Hívás megszakítása 4 (#OF, túlcsordulás), ha eflags.of \u003d 1

8086

ba

Leírás:

Csapat INT 3. A 3. megszakítás létrehozása és az INT N parancsával azonos művelet leírása, azzal a különbséggel, hogy a megszakítási szám itt nincs közvetlenül a működési kódban, de implicit módon megegyezik 3.

Ez a megszakítás a debugger által történő használatra szolgál, amely különleges egyhangú parancsot helyez el. INT 3. (CCCH kód) az első parancs bájt helyett vagy az egyszeri parancsok helyett.

Van egy második módja annak, hogy ezt a megszakítást két bájtos kóddal (CD03H-kód) segítségével hívja. de ez a módszer A gyakorlatban nem alkalmazható, az összes x86 szerelvény alapértelmezett mnemonikával történik INT 3. Egyhangú parancsként CCH kóddal (de ez nem zárja ki a két bájt kézi programozásának lehetőségét). A kód mérete mellett az egyszeri és két byte parancsok feldolgozási folyamata eltérő. INT 3.. Az EV86 üzemmódban (CR4.VME \u003d 1) egyszemélyes parancs (CR4.VME \u003d 1) által generált megszakítás nem ki van téve a megszakítási átirányítási kártya átirányításának (a 2. üzemmódban leírt módon, a 3. üzemmódban, az 5. üzemmódban), és mindig a védett mód-kezelő feldolgozza az IDT táblázatban található leírón keresztül. Ezenkívül a V86 üzemmódban az IOl mezőellenőrzések nem ellenőrzik ezt a megszakítást, és ennek megfelelően a hiba nem generálható #GP hiba, amikor az eflags.iopl< 3, то есть однобайтная команда не является IOPL-чувствительной .

Művelet:

Az itt bemutatott algoritmus nem csak a processzor viselkedését írja le a parancs végrehajtásakor INT 3. Külső megszakítás vagy létrehozás egy különleges helyzet.

Aztán Goto. Igazi cím mód;

Ha (eflags.vm \u003d 1 és eflags.iopl< 3 AND

(CR4.VME \u003d 0 vagy CR4.VME \u003d 1 és IRB [N] \u003d 1)

) (* IRB [N] - bit, amely megfelel a megszakításnak a megszakítások átirányításának térképében *)

#Gp (0); (Szoftver megszakítása INT N IN MODE: (1) V86 az eflags.iopl< 3, (2) EV86 Режим 2 *)

MÁS. (* Védett mód vagy V86 / EV86 * mód)

Ha (eflags.vm \u003d 1 és cr4.vme \u003d 1 és

(Int n) és IRB [n] \u003d 0)

Egyébként goto. Védett mód.; (* Hardver megszakítások, speciális helyzetek; int n szoftver megszakítása: (1) Védett mód, (2) V86 eflags.iopl \u003d 3, (3) EV86 mód 1 vagy 4 *)

Valódi addres-mód:

Ha ((megszakítási szám * 4) + 3 meghaladja a szegmenst, ha az IVT-megszakítási vektorok táblázathoz való hozzáférés esetén a #GP; Fi;

Ha (nincs hely 6 bájtra a veremben), akkor #ss; Fi;

Eflags.if \u003d 0; (* A megszakítások lobogója visszaállítása *)

Eflags.tf \u003d 0; (* Flag csapdák visszaállítása *)

Eflags.ac \u003d 0; (* Állítsa vissza az Alignment Control mód jelölését *)

CS \u003d IVT [Megszakítási szám * 4] .Káláló;

EIP \u003d IVT [Megszakítási szám * 4]. FFFSet és 0x0000FFFFH;

(* A munka folytatása valódi címzésben ... *)

EV86 mód: (* Cr0.pe \u003d 1, eflags.vm \u003d 1, cr4.vme \u003d 1, EV86 mód egy int n program megszakítása, IRB [N] \u003d 0 - MODE 3 vagy MODE 5 *)

Ha (a V86 feladatcsomagban nincs hely 6 bájtra), akkor #ss (0); Fi;

tempflags \u003d zászlók;

tempflags.nt \u003d 0;

Ezután eflags.if \u003d 0; (* A megszakítások engedélyének alaphelyzetbe állítása *)

tempflags.if \u003d eflags.vif;

Eflags.vif \u003d 0; (* A megszakítások virtuális zászlójának visszaállítása *)

Eflags.tf \u003d 0; (* Flag csapdák visszaállítása *)

Nyomógomb (tempflags);

(* A hibakódok nincsenek beírva a veremre *)

CS \u003d IVT_V86 [Megszakítási szám * 4] .Káláló; (* Az IVT_V86 megszakítási vektorok táblázata a V86 * feladat címterületének elején található)

EIP \u003d IVT_V86 [Megszakítási szám * 4] .offset és 0x0000FFFFH; (* Az idősebb 16 bites EIP-regiszter visszaállítása *)

(* Az EV86-ban folytatott munka ... *)

VÉDETT MÓD: (* CR0.PE \u003d 1, hardveres megszakítások, speciális helyzetek; int n szoftver megszakítása üzemmódban: (1) Védett mód, (2) V86 eflags.iopl \u003d 3, (3) EV86 mód 1 vagy 4 * mód

Ha ((megszakítási szám * 8) + 7 nem esik az IDT-ben) Tan #GP (megszakítási szám * 8 + 2 + ext); Fi;

(* A továbbiakban, a hibakód paraméterek, a kifejezés +2 eszköz beállításával a hibakódot a hibakód, és a feltételeket + ext - eszközt beállítása EXT hibakódot összhangban, hogy a hiba a megszakítást okozó programot EXT \u003d 0 vagy külső ext \u003d 1 *)

AR-leíró bájt kell beállítani a megszakítás átjáró, csapda átjáró vagy egy feladatot átjáró, különben #gp (megszakítás száma * 8 + 2 + EXT);

Ha (szoftver megszakítása vagy különleges helyzet) (* Ezek. Az egyik esetben int n, int 3, int01, kötött vagy *)

Ha (CPL\u003e DPL Gateway)

#GP (megszakítási szám * 8 + 2); (* CR0.PE \u003d 1, DPL Gateway< CPL, программное прерывание *)

Az átjárónak jelen kell lennie, ellenkező esetben #np (megszakítási szám * 8 + 2 + ext);

Ha (átjáró feladatok)

Aztán Goto. Feladat-kapu.;

Menj. Csapda-vagy int-kapu; (* CR0.PE \u003d 1, megszakítási vagy csapda átjáró *)

Trap vagy Int-Gate: (* Védett mód vagy V86 / EV86 mód, csapda vagy megszakítási átjáró *)

Az új CS-választó ellenőrzése az átjáró leírójában, és a megfelelő leíró LDT vagy GDT:

A választónak nem kell nulla, ellenkező esetben, a #GP (ext);

A választókindexnek a leírók táblázatba kell tartoznia, különben #GP (választó + ext);

A kiválasztott fogantyúnak szegmensleíró kódnak kell lennie, különben #GP (választó + ext);

A szegmensnek jelen kell lennie (p \u003d 1), egyébként #np (választó + ext);

Ha (nem koordinált kódszegmens) és (kódszegmens dpl< CPL)

Ha eflags.vm \u003d 0

Aztán Goto. Int-to-inter-private; (* Cr0.pe \u003d 1, eflags.vm \u003d 0, megszakítási vagy csapda átjáró, inkonzisztens kódszegmens, DPL kód szegmens< CPL *)

Más (* eflags.vm \u003d 1 *)

Ha (az új kódszegmens dpl ≠ 0), akkor a #GP (választó kód szegmens + ext); Fi;

Menj. Int-from-v86 mód;(* Cr0.pe \u003d 1, eflags.vm \u003d 1, megszakítási vagy csapda átjáró, DPL kód szegmens \u003d 0, cpl \u003d 3 *)

MÁS. (* CR0.PE \u003d 1, megszakítási vagy csapda átjáró, konzisztens kódszegmens vagy következetlen kód szegmens dpl \u003d cpl *)

Ha eflags.vm \u003d 1, akkor #GP (kódszegmens választó + ext); Fi;

Ha ((megfelelő megfelelõ) vagy (kódszegmens DPL \u003d CPL)))

Aztán Goto. Int-to-intra-priv; (* CR0.PE \u003d 1, megszakítási vagy csapda átjáró, DPL kód szegmens ≤ CPL egy következetes szegmenshez, kódszegmens DPL \u003d CPL az inkonzisztens szegmenshez *)

Más #gp (kódszegmens választó + ext); (* DPL\u003e CPL egy következetes szegmenshez vagy DPL ≠ CPL az inkonzisztens szegmenshez *)

Int-to-Inter-Priv: (* Védett mód, megszakítás vagy csapda átjáró, inkonzisztens kódszegmens, DPL kódszegmens< CPL *)

Ha (jelenlegi TSS 32 bites)

Tssstackaddress \u003d (új kód szegmens DPL * 8) + 4

Ha ((tssstackaddress + 5)\u003e TSS Limit) (* (Tssstackaddress + 7)\u003e

Hírek \u003d [TSS + TSSSTACKADDRESS & 4] BASE; (* 2 bájt betöltve *)

(* 4 bájt betöltve *)

MÁS. (* Aktuális TSS 16 bites *)

Tssstackaddress \u003d (új kódszegmens DPL * 4) + 2

Ha ((tssstackaddress + 3)\u003e TSS Limit) (* (Tssstackaddress + 4)\u003e TSS Limit - néhány processzor modellhez *)

Ezután #ts (az aktuális TSS + EXT választója);

NewesP \u003d [TSS + TSSSTACKADDRESS BASE]; (* 2 bájt betöltve *)

Hírek \u003d [TSS + TSSSTACKADDRESS + 2 BASE]; (* 2 bájt betöltve *)

Az RPL választónak meg kell egyeznie az új kódszegmens DPL-jével, különben #ts (SS Selector + EXT);

A Stack szegmens DPL-nek meg kell egyeznie az új kódszegmens DPL-jével, egyébként #ts (SS Selector + EXT);

Ha (32 bites átjáró)

Ezután az új veremnek 20 bájtra kell történnie (24 byte, ha hibakód van), egyébként #ss (ext)

Máskülönben az új veremnek 10 bájtra kell történnie (12 bájt, ha hibakód van), egyébként #ss (ext)

SS: ESP \u003d TSS (hírek: newesp); (* Töltse le az új SS-t és az ESP értékeket a TSS *)

Ha (32 bites átjáró)

Azután.

Egyébként cs: IP \u003d kapu (választó: offset);

Az SS-leíró letöltése az SS-regiszter rejtett részében;

Ha (32 bites átjáró)

Nyomja (hosszú mutató a régi veremhez - SS: ESP);

Nyomja meg (hosszú mutató a visszatérési ponthoz - CS: EIP); (* 3 szó kiegészül 4 *)

Nyomógomb (hibakód);

Nyomja meg (hosszú mutató a régi veremhez - SS: SS: SS); (* 2 szó *)

Nyomja meg (hosszú mutató, hogy visszatérjen pont - CS: IP); (* 2 szó *)

Nyomógomb (hibakód);

CPL \u003d az új kódszegmens dpl;

Ha (megszakítási átjáró), akkor az eflags.if \u003d 0 fi; (* Állítsa vissza a megszakítási zászlót *)

Eflags.rf \u003d 0;

(* A munka folytatása védett módban nagy kiváltságokkal rendelkező szinten ... *)

Int-from-v86 mód: (* V86 / EV86 mód, megszakítás vagy csapda átjáró, dpl \u003d 0, cpl \u003d 3 *)

(* Az aktuális TSS mindig 32 bites üzemmódban van V86 *) *)

Ha (TSS Limit< 9) (* TSS LIMIT< 11 - для некоторых моделей процессоров *)

Ezután #ts (az aktuális TSS + EXT választója);

Hírek \u003d [bázis TSS + 8]; (* 2 bájt betöltve *)

NewesP \u003d [bázis TSS + 4]; (* 4 bájt betöltve *)

Ellenőrizze a hírek új veremszegmensének és az LDT vagy GDT megfelelő leírójának választóját:

A választó nem lehet nulla, egyébként #ts (ext);

A választókindexnek a leíró táblázatba kell esnie, ellenkező esetben a #ts (SS selector + ext);

Az RPL választónak nulla, egyébként #ts (SS Selector + EXT);

A Stack szegmens DPL-nek nulla lehet, különben az #ts (SS Selector + EXT);

A leírónak rendelkeznie kell egy adatleíró leíró formátummal (W \u003d 1), egyébként #ts (SS Selector + EXT);

A szegmensnek jelen kell lennie (p \u003d 1), egyébként #ss (SS Selector + EXT);

Ha (32 bites átjáró)

Az új veremnek 36 bájtra kell történnie (40 bájt, ha hibakód van), egyébként #ss (ext)

Az utasítás új mutatója az új kódszegmensen belül kell lennie, egyébként #GP (ext); (* Az utasításmutatót az Offset Mező értéke határozza meg az átjáró leírójából *) *)

Tempeflags \u003d eflags;

Eflags.vm \u003d 0; (* A processzor a V86 üzemmódból származik, hogy megszakítsa a védett módban *)

Ha (megszakítási átjáró)

Ezután eflags.if \u003d 0;

Cpl \u003d 0; (* Váltás nullára Privilege Level *)

SS: ESP \u003d TSS (hírek: newesp); (* Letöltés SS0 és ESP0 értékek a TSS *)

Nyomja meg (GS);

Nyomja meg az (FS); (* Két szóra kiterjed *)

Nyomja meg (DS); (* Két szóra kiterjed *)

Push (ES); (* Két szóra kiterjed *)

Gs \u003d 0; (* A szegmensregiszterek visszaállnak. Elfogadhatatlan, hogy a nulla választók későbbi használatát biztonságos üzemmódban *)

Nyomógomb (temps); (* Két szóra kiterjed *)

Nyomja meg (tempeflags);

Nyomja meg (CS); (* Két szóra kiterjed *)

Nyomógomb (hibakód); (* Ha jelen van, 4 bájt *)

CS: EIP \u003d kapu (választó: offset); (* Töltse le a választót: Offset a 32 bites átjáró leírójából *)

Egyébként (* 16 bites átjáró *)

Az új veremnek 18 bájtra kell történnie (20 bájt, ha hibakód van), egyébként #ss (ext)

(* A 16 bites regiszterek kötegének megmentése hasonlóan a 32 bites átjáróhoz hasonlóan történik *)

(* Visszatérés a megszakításról az IRET paranccsal vissza a V86 módba a 16 bites szegmensből, mivel a VM-zászló nem kerül mentésre a veremben, és nem kerül visszaállítani az eflagok képétől * )

(* A védett módban végzett munka folytatása a jogosultságok nulla szintjén ... *)

INT-TO-INTRA-PRIR: (* Cr0.pe \u003d 1, dpl \u003d cpl vagy konzisztens szegmens dpl ≤ cpl *)

Ha (32 bites átjáró)

Ezután az új veremnek 12 bájtra kell történnie (16 bájt, ha hibakód van), egyébként #ss (ext)

Egyébként az új veremnek 6 bájtra kell történnie (8 bájt, ha hibakód van), egyébként #ss (ext)

Az utasítás új mutatója az új kódszegmensen belül kell lennie, egyébként #GP (ext);

Ha (32 bites átjáró)

Nyomja meg (hosszú mutató, hogy visszatérjen); (* 3 szó kiegészül 4 *)

CS: EIP \u003d kapu (választó: offset); (* Töltse le a választót: Offset a 32 bites átjáró leírójából *)

Nyomógomb (hibakód); (* Ha jelen van, 4 bájt *)

Nyomja meg (hosszú mutató, hogy visszatérjen); (* 2 szó *)

CS: IP \u003d kapu (választó: offset); (* Letöltés választó: Offset a 16 bites átjáró leíró *)

Nyomógomb (hibakód); (* Ha van, 2 bájt *)

Töltse le a CS-leírót a CS-regiszter rejtett részében;

Ha (megszakítási átjáró), akkor az eflags.if \u003d 0; Fi;

(* A védett módban való munka folytatása a kiváltság szintje megváltoztatása nélkül ... *)

Task-Gate: (* CR0.PE \u003d 1, TASK GATEWAY *)

Ellenőrizze a TSS választót a Feladat átjáró leírásából:

A választónak be kell állítania a GDT-t (bit ti \u003d 0), egyébként #GP (TSS Selector + EXT);

A választókindexnek a GDT táblázatba kell esnie, különben a #GP (TSS Selector + EXT);

A kiválasztott választónak megfelelő megfelelő TSS-leíró ellenőrzése:

A TSS-leírónak rendelkeznie kell egyfajta szabad TSS-t (type.b \u003d 0), egyébként #GP (TSS Selector + EXT);

A TSS-nek jelen kell lennie (p \u003d 1), egyébként #np (TSS Selector + EXT);

Kapcsolási feladatok (mellékletekkel) TSS-ben; (* Itt a "melléklet segítségével" azt a tényt jelenti, hogy az új feladat kontextusának inicializálásakor az EFLAGS.NT \u003d 1 lobogó, és a TSS-választó (régi) feladat a TSS szegmensben (régi) kerül átmásolni Szegmens - Nézze meg a címzést és a multitaskingot: Montisascia támogatás *)

Ha (a megszakítás egy különleges helyzet a hibakóddal)

A kötegnek a hibakód, egyébként #ss (ext) helynek kell lennie;

Nyomógomb (hibakód);

Az EIP utasítás mutatója a CS szegmensbe esnie kell, egyébként #GP (EXT);

(* Az új feladat kontextusának betöltése további ellenőrzések, amint azt a címkézés és a multitasking: multiadalitás támogatási eszköz *)

(* A munka folytatása egy új feladat összefüggésében ... *)

A védett rezsim különleges helyzetei:

INT 3.De a különleges helyzet külső megszakításának vagy generációjának kézhezvételét követően is. Bit Ext. A külső megszakítás hibakódjában).

  • leíró vektor (index) a megszakítások nem a megszakítási leírások (IDT) táblázatában vannak;
  • leíró vektor (index) a megszakítás, nem csapda átjáró leíró, megszakítási átjáró vagy feladat átjáró;
  • van egy szoftvermegszakítás vagy szoftver speciális helyzet (azaz az egyik eset: int n, int 3, int01, kötött vagy be) és egyszerre jelenlegi jogosultságszint (CPL) Feladatok több kiváltságszintek(Dpl) gateway leíró Az IDT asztalról -
  • szegmensválasztó a megfelelő feldolgozva vektor (Index) A csapda átjáró leírójának megszakításának megszakítása, a megszakítási átjáró vagy a feladat átjáró nulla választó;
  • a Trap Gateway szegmensszegmense vagy a megszakítási átjáró leíró szegmensszegmense kiválasztása nem tartozik a leíró táblázatba;
  • a TSS szelektor indexe a feladat átjáró leírójának megfelelő megszakításából nem tartozik globális leíró asztal (GDT);
  • leíró Az új kódszegmens nem kódszegmens leíró;
  • (DPL) új koordinált kódszegmens aktuális szintpivile (CPL) feladatok -
  • a kiváltságok leíró szintje (DPL) az új következetlen kódszegmens nem egyenlő jelenlegi jogosultságszint (CPL) feladatok -
  • tSS választó a feladat átjáró leírójának megfelelő megszakításából jelzi helyi asztalleírók (Ldt);
  • az új feladat TSS leírója meg van jelölve elfoglalt- típusa.b ≠ 1.
  • a cím, amelyen az új értéket olvasni kell verem mutató (SS: ESP), túlmutat a TSS szegmensen;
  • az új verem szegmens kiválasztása nulla választó;
  • az új verem szegmens választóindexe nem esik a leíró táblázatba;
  • a kiváltságok kért szintje (RPL) Az új verem szegmens kiválasztása nem egyenlő (DPL) új kódszegmens -
  • a kiváltságok leíró szintje (DPL) az új verem szegmens nem egyenlő a kiváltságok leíró szintje (DPL) új kódszegmens -
  • az új verem szegmens nem a felvételhez rendelkezésre álló adatszegmens -
  • a megfelelő megszakítja a csapda átjáró leíróját, a megszakítási átjárót, a feladat átjárót vagy a TSS-leírót kíséret nélküli (Bit p leíró visszaáll);
  • az új kódszegmens nincs jelen (bIT P. A szegmens leírója visszaáll.
  • amikor a veremre írva (beleértve az új verembe, ha a verem kapcsoló) értékek címek visszatérése, verem mutató, zászlók vagy a hibakód alkalmas a köteg szegmens megengedett határára;
  • az új verem szegmens nincs jelen (bit p szegmens leírója visszaáll).

Különleges helyzetek valódi címzési rendszer:

Az itt bemutatott speciális helyzetek listája a processzor viselkedését nemcsak a parancs végrehajtásakor jellemzi INT 3.De a különleges helyzet külső megszakításának vagy generációjának kézhezvételét követően is.

A V86 mód különleges helyzetei:

Az itt bemutatott speciális helyzetek listája a processzor viselkedését nemcsak a parancs végrehajtásakor jellemzi INT 3.De a különleges helyzet külső megszakításának vagy generációjának kézhezvételét követően is. Bit Ext. A hibakódban a megszakított eseményprogram (

Minden DOS funkciót a 21H megszakításával (33. decimális jelölésben) hívják. A DOS első verziója 42 funkciót tartalmazott. A második, 33 további funkciót adnak hozzá, amelyek az összes későbbi verzióban tárolódnak. A konkrét funkció kiválasztása a megfelelő szám rögzítésével történik az AH regiszterhez.

Funkció 02: Kimenet egyetlen szimbólum a képernyőn

Az egyik karakter kimenete a használt számítógép képernyőjén

21H megszakítás funkció 02:

mOV DL,<код выводимого символа>

A kimeneti szimbólum a kurzor pozíciójában (bármi is van rögzítve), amely után a kurzor jobbra mozog. Ha a kurzor a képernyő karakterlánc végén volt, akkor a következő sor elejére lép, és ha a kurzor a képernyő utolsó sorának végén volt, akkor a képernyő tartalma felfelé mozog, és az üres A karakterlánc megjelenik az alján, és a kurzor telepítve van.

A 7, 8, 9, 10 (0H) kódok és a 13 (0HDH) kódok speciális módon történnek. A 7-es kóddal (Bell, Call) a képernyőn nincs kiemelve (és a kurzor nem változik), és okozza hangjelzés. Symbol kóddal 8 (Backspase lépés vissza) Visszatér a kurzort egy pozícióval balra, kivéve, ha ez volt a bal sorban a húr. A 9 kóddal rendelkező szimbólum (fül, fül) a kurzort jobbra a legközelebbi pozícióba helyezi, több 8. A szimbólum a 10 kóddal (vonaladagolás, vonal fordítása) mozgatja a kurzort a következő sorban, így ugyanabban hagyja oszlop. Szimbólum a 13 kóddal (Carrige Returede, a kocsi visszatérése) A kurzort az aktuális vonal elejére állítja be; Következtetés A 13. és 10. kóddal rendelkező karakterek sorában azt jelenti, hogy a kurzort a következő sor elejére fordítja.

Funkció 9: A kijelzőn megjelenít egy karakterláncot

A karakterlánc (szimbólumszekvenciák) megjelenítéséhez természetesen használhatja a 02 funkciót, de egy vételnél 21 órás megszakítási funkcióval végezhető el:

DS: DX: \u003d Start sorcíme

Mielőtt erre a funkcióra hivatkozna, a memória szegmens számát a DS-regiszterbe kell helyezni, amelyben a kimeneti vonal található, és a DX REGISZTRÁCIÓBAN - a Soros eltolás ezen a szegmensben. Ugyanakkor a vonal végén egy $ szimbólum (24h kód) kell lennie, amely a vonal végének jele, és nem jelenik meg.

Bár ez a funkció sokat lehet kényelmesebb funkciók Picky kimenet a képernyőn (2. és 6. függvény), hátránya, hogy egy teljesen rendes $ szimbólumot használnak string limiterként. Ez egy másik oldali termékkompatibilitás CP / M.

A fejlett DOS operációs rendszer karakterláncfunkcióként működik Chr. $ (0). Ez megfelel az Unix operációs rendszerben és az SI programozási nyelvben elfogadott megállapodásoknak.

Nincs olyan dolog, amely számokat jelenít meg. Ilyen műveletet szükség esetén a figyelembe vett funkciók alapján kell végrehajtani.

4CH funkció: a program befejezése

Az összes művelet befejezése után a program köteles visszaadni az operációs rendszergazdálkodást, hogy a felhasználó továbbra is dolgozzon a számítógépen. Az ilyen visszatérítést a 21 órás megszakítási funkció hajtja végre, amelyet a program végén helyezünk el:

mozog al,<код завершения>

Minden egyes program, amelyet általában beszél, köteles jelenteni, sikeresen vagy nem teljesítette munkáját. Az a tény, hogy bármely programot más programból (például az operációs rendszerből) hívnak, és néha a programnak megfelelően hívják, hogy megfelelően működjenek, tudnod kell, hogy a hívott program teljesített-e, vagy egy hiba. Ezeket az információkat továbbítja a kódot a program befejezéséhez (néhány szám), amely nem lehet nulla, ha a program működött rendesen, és nem nulla (amelyet kifejezetten meghatározott minden egyes esetben) másként nem rendelkezik. (Megtanulhatja a program befejezési kódját a 4DH megszakítási funkcióval 21h.

Mi az összeszerelő

Az összeszerelő egy alacsony szintű programozási nyelv. Minden egyes processzor esetében van egy összeszerelő. Programozás az összeszerelőn közvetlenül a számítógépes eszközzel dolgozik. A forrás szövege assembly nyelven áll parancsok (memorizálás), amely után összeállítása, átalakul a processzor parancskódokat.

A programok fejlesztése az összeszerelőn nagyon nehéz dolog. Ahelyett, hogy egy hatékony programot kapsz. Az összeszerelő programok akkor íródnak, amikor minden processzorciklus fontos. Az összeszerelőben konkrét parancsokat ad a processzornak és az extra szemetet. Ezt nagy sebességgel érik el a program nagy sebességével.

Az összeszerelővel kompetens használatához ismernie kell a mikroprocesszoros szoftvermodellt. A programozó szempontjából a mikroprocesszoros rendszer a következőkből áll:

  1. Mikroprocesszor
  2. memória
  3. I / O eszközök.

A szoftvermodellt jól ismertetjük a szakirodalomban.

Összeszerelő szintaxis

A programsorozat általános formátuma az összeszerelőn

<Метка>: <Оператор> <Операнды> ; <Комментарий>

Címkék. A címke karakterekből és adhéziós jelekből állhat. A címkéket feltételes és feltétel nélküli átmeneti műveletekben használják.

Operátor mező. Ez a mező egy csapat mnemonikus. Például Mnemonica mov.

Operand mező. Az operandus csak akkor jelen lehet, ha az üzemeltető jelen van (kezelő mező). Előfordulhat, hogy az operandok nem lehetnek, és talán több. Az operandusok olyan adatok lehetnek, amelyeket néhány műveletet kell végrehajtania (előre, hajtás stb.).

Megjegyzés mező. A megjegyzés szükséges a program verbális támogatásához. Minden, ami a szimbólum mögött van ; Megjegyzésnek számít.

Az összeszerelő nyelv első programja

Ez a cikk egy összeszerelőt használ az I80x86 processzorhoz, és a következő szoftvereket használjuk:

  • Szöglet - Borland Turbo Assembler - Compiler
  • TLINK - Borland Turbo Linker - Kommunikációs szerkesztő (linker)

A beton, a 2.0.

A hagyomány szerint első programunk visszavonja a "Hello World!" Karakterláncot a képernyőn.

File Sample.asm.

Modell kicsi; Memória modell. 100h; A stack size.data beállítása; A Hellomsg DB program "Hello World!", 13.10, "$" .Code; A MOV AX kódszegmens kezdete, @ adatok; Az adatszegmens címét elküldjük az AX MOV DS Regisztrációhoz, AX; A DS-regiszter telepítése a MOV AH adatszegmenshez; DOS sor kimeneti funkció a MOV DX képernyőn, az Offset Hellomsg; Meghatározzuk az ellensúlyt az INT 21H vonal elejére; Megjelenítjük a MOV AX-karakterláncot, 4C00H; A DOS funkció kilép az INT 21H programból; Kilépés a végéből

Mivel észreveheted, hogy a program szegmensekre oszlik: adatszegmens, kódszegmens, és van egy másik verem szegmens.

Fontolja meg mindent rendben.

Irányelv.model Small Megadja a memória modellt. A kis modell 1 szegmens a kódhoz, 1 szegmenshez az adatokhoz és a veremhez Az adatok és a verem ugyanabban a szegmensben van. Vannak más memória modellek, például: apró, közepes, kompakt. A választott memória modelltől függően a program szegmensei átfedhetnek, vagy külön szegmensekkel rendelkezhetnek a memóriában.

Irányelv.Stack 100h állítja be a mérete a verem. A köteg szükséges néhány információt a későbbi helyreállítással. Különösen a köteget a megszakítások során használják. Ebben az esetben a tartalmát a zászlók zászló regisztrálni, CS Regisztráció és IP Regisztráció vannak egymásra rakható. Ezután van egy megszakítási program, majd a regiszterek értékei visszaállnak.

  • A Flags Flags Regiszter olyan jeleket tartalmaz, amelyek a processzorhoz való parancs végrehajtása után alakulnak ki.
  • A CS Regisztráció (kódszegmens) tartalmazza a kódszegmens címét.
  • Az IP-regiszter (utasítás mutató) egy parancsmutató. Ez tartalmazza a címét a parancsot, hogy be kell fejezni a következő (cím viszonyítva CS kód szegmens).

Több részletes leírás Egy egyszerű cikk kereteinek megadása.

Az irányelv.data meghatározza a program adatszegmensét. Az adatszegmens meghatározza a "Változók", azaz. A szükséges adatok alatt van egy memória redundancia. Után.Data megy karakterlánc
Hellomsg db "Hello World!", 13.10, "$"

Itt a Hellomsg egy szimbolikus név, amely megfelel a "Hello World!" Sorának megkezdésével. (idézőjelek nélkül). Ez az, hogy ez az első szimbólumunk címe az adatszegmenshez képest. A DB irányelv (Define byte) meghatározza a bypassban elérhető memóriaterületet. 13.10 - Szimbólumkódok Új sor És a kocsi visszatérése, és a $ szimbólum szükséges a 09h DOS funkció helyes működéséhez. Tehát a karakterláncunk 15 bájt emlékezetében fog elfoglalni.

Irányelv. A kód határozza meg a program kódszegmense (CS - kódszegmense) kezdetét. Ezután a programok, amelyek a csapatok mnemonikáját tartalmazzák.

Elmondom neked a csapat mozdulatait.

mov.<приёмник>, <источник>

Mov parancs - Küldés parancs. Továbbítja a forrás tartalmát a vevőegységbe. Az átvitel lehet regiszterregiszter, regiszter, memória regiszter, de nincs átviteli memória-memória. Minden áthalad a processzor regisztereken.

Az adatokkal való együttműködéshez be kell állítania az adatszegmens regisztert. A beállítás az, hogy rögzítjük a @Data adatszegmens címét a DS-regiszterben (adatszegmens). Közvetlenül rögzítse a címet ebben a nyilvántartásban nem lehetséges - ez az architektúra, így a fejszétlistát használjuk. AX-ben kódszegmens címet írunk

ezután elküldjük a Tartalomjegyzék tartalmát a DS-regiszterbe.

Ezután a DS-regiszter tartalmazza az adatszegmens címét. A DS: 0000H cím tartalmazza a H szimbólumot. Feltételezem, hogy tudod a szegmensekről és az eltolásokról.

A cím két összetevőből áll<Сегмент>:<Смещение>ahol a szegmens 2 bájt és offset - 2 byte. A memóriahely eléréséhez 4 bytes kapcsolja ki.

mov ah, 09h
MOV DX, Offset Hellsg
INT 21H.

Itt vagyunk az AH regiszter számokat ír 09h - ez a szám a 21. megszakítás funkció, amely megjeleníti a string a képernyőn.

A következő sorban megírjuk a címet (zavarba) a DX Regisztrálás sorának elejére.

Ezután hívjuk a 21h megszakítást a DOS funkciók megszakítása. Megszakítás - ha a végrehajtott program megszakad, és a megszakítási program megkezdődik. Megszakítási számmal meghatározzuk a DOS szubrutin címét, amely a karakterláncot a képernyőre mutatja.

Valószínűleg kérdésed lesz: Miért írjuk meg a 09h funkció számát az Ah-Regisztrációban? És miért van az eltolás a DX regiszterre írt karakterlánchoz?
A válasz egyszerű: Minden egyes funkció esetében meghatározott regiszterek, amelyek bemeneti adatokat tartalmaznak ehhez a funkcióhoz. Nézze meg, hogy mely regiszterekre van szükség bizonyos funkciók, amelyeket segíthet "e.

mOV AX, 4C00H
INT 21H.

mOV AX, 4C00H - Funkciószámot küldünk az AX-regiszterhez. Funkció 4C00H - Lépjen ki a programból.

iNT 21H - Végezze el a megszakítás (valójában kijöjjön)

a vége a program vége.

A végső irányelv után a fordító figyelmen kívül hagyja mindent, így mindent írhatsz, bármi :)

Ha elolvastad a végét, akkor hős vagy!

Maiko G.V. Összeszerelő az IBM PC számára: - M.: "Üzleti tájékoztatás", "Sirin" 1999 - 212 p.



Tetszett a cikket? Oszd meg