Kontakty

Úvod do jazyka Assembler. Špeciálne situácie režimu V86

Maskréry Mash, Tasm a Wasm sa navzájom líšia. Vytvorenie jednoduchých programov pre nich prakticky nemá rozdiely, s výnimkou samotnej zostavy a rozloženia.

Tak, náš prvý program pre MASM, TASM a WASM, ktorá zobrazuje anglické písmeno "A" v aktuálnej polohe kurzora, to znamená vľavo horný roh Obrazovka:

Model Tiny .Code Org 100H Start: MOV AH, 2 MOV DL, 41H Int 21H INT 20H Koniec Spustenie Tento text môže byť napísaný v akomkoľvek jednoduchom textový editor - Napríklad v zápisníku z Windows (ale nie v Word a nie v inej "zložitej"). Avšak, odporúčam "Rozšírený" textový editor s osvetľovaním syntaxe, napríklad PSPAD (pozri časť). Potom tento súbor uložte pomocou Extension.Asmers, napríklad v priečinku myProg. Zavolajme najďalej súbor. Takže sme dostali: c: myprogasty.

POZNÁMKA
Upozorňujeme, že v prvom tíme sme nahrali 2 namiesto 02h. MASM, TASK A WASM, ako EMU8086, priznať takú "slobodu". Aj keď môžete písať 02H - nebudú žiadne chyby.

Vysvetlenie programu:

.Model Tiny - 1. riadok. Smernica.Model definuje pamäťový model pre konkrétny typ súboru. V našom prípade je to súbor s rozšírením COM, takže vyberieme malý model, v ktorom sú kombinované segmenty kódu, dát a zásobníka. Tiny model je navrhnutý tak, aby vytvoril súbory typu A som.

.code. - 2. riadok. Táto smernica začína segment kódu.

Org 100h. - 3. reťazec. Tento príkaz nastavuje hodnotu počítadla softvéru v 100h, pretože pri načítaní súboru Som súborov v pamäti, DOS vyberie prvých 256 bajtov na dátový blok PSP pre prvých 256 bajtov (desatinné číslo 256 rovné hexadecimálnemu 100H). Kód programu sa nachádza až po tomto bloku. Všetky programy, ktoré sú zostavené do súborov COM, musia začať touto smernicou.

Štart: MOV AH, 02H - 4. riadok. Štartový štítok sa nachádza v prednej časti prvého príkazu v programe a bude použitá v smernici o konečnom smere na určenie, ktorý príkaz začína program. Instruction MOV umiestni hodnotu druhého operandu v prvom operande. To znamená, že hodnota 02h je umiestnená v registri SK. Na čo sa to robí? 02h je funkcia Dosova, ktorá zobrazuje symbol na obrazovke. Píšeme program pre DOS, takže používame príkazy operačný systém (OS). A píšeme túto funkciu (alebo skôr jeho číslo), je v registri SK, pretože prerušenie 21h používa tento konkrétny register.

MOV DL, 41H - 5. linka. Kód symbolu "A" sa zadáva do registra DL. Kód "A" podľa normy ASCII je číslo 41h.

Int 21h. - 6. riadok. Toto je najviac prerušenie 21H - príkaz, ktorý spôsobuje funkciu systému DOS uvedený v registri SK (v našom príklade je funkcia 02H). Príkaz INT 21H je hlavným prostriedkom interakcie programov z operačného systému.

Int 20h. - 7. linka. Toto prerušenie, ktoré vykazujú operačný systém o produkte z programu a prenosu riadenia console Application. V prípade, že program je už zostavený a spustený od systému OS, príkaz INT 20H nás vráti na OS (napríklad v DOS).

Koniec - 8. linka. Konečná smernica dopĺňa program v rovnakom čase, v ktorom sa uvedie, ktorý štítok by sa mal vykonať.

Int 3.

Prerušenie hovoru 3 (#BP, bod zastavenia)

8086

int 3.

Cd iB.

Int. iMM8.

Výzva prerušuje iMM8.

8086

int 13.

Do

Prerušenie hovoru 4 (#Of, Prepad) Ak EFLAGS.OF \u003d 1

8086

do

Popis:

Tím Int 3. Je určený na vytvorenie prerušenia 3 a opísať operáciu identickú s príkazom INT N, okrem toho, že číslo prerušenia tu nie je prítomné priamo v operačnom kóde, ale implicitne nastavené rovno do 3.

Toto prerušenie je určené na používanie debuggerom, ktorý umiestni špeciálny príkaz s jedným tónom. Int 3. (CCCH kód) namiesto prvého príkazového bajtu alebo namiesto jednosmerných príkazov.

Existuje druhý spôsob, ako zavolať na tento prerušenie pomocou dvojbajtového kódu INT 3 (CD03H kód). ale táto metóda V praxi sa neuplatňuje, všetky zostavy X86 sú predvolené štandardne mnemonics Int 3. Ako príkaz s jedným tónom s CCH kódom (ale to nevylučuje možnosť manuálneho programovania dvojakého bajtu). Okrem veľkosti kódu je proces spracovania jednotlivých a dvojbajtových príkazov iný. Int 3.. Prerušenie generované jedným ovládačom v režime EV86 (CR4.VME \u003d 1) nie je vystavený presmerovaniu karty prerušenia presmerovania (ako je popísané pre režim 2, režim 3, režim 5) a je vždy spracovaný pomocou chráneného režimu Prostredníctvom deskriptora v tabuľke IDT. Okrem toho, v režime V86, kontroly poľa IOPL nie sú kontrolované pre toto prerušenie, a preto chyba nemôže byť generovaná chyba #GP, keď EFLAGS.IOPL< 3, то есть однобайтная команда не является IOPL-чувствительной .

Prevádzka:

Algoritmus tu predstavuje nielen správanie procesora pri vykonávaní príkazu Int 3. Externé prerušenie alebo generovanie špeciálnej situácie.

Potom goto. Real-Adresa-Mode;

Ak (eflags.vm \u003d 1 a eflogs.iopl< 3 AND

(CR4.VME \u003d 0 alebo CR4.VME \u003d 1 a IRB [n] \u003d 1)

) (* IRB [n] - bit, čo zodpovedá prerušeniu n v mape presmerovania prerušení *)

#Gp (0); (Software Intert N v režime: (1) V86 na EFLAGS.IOPL< 3, (2) EV86 Режим 2 *)

Inak. (* Chránený režim alebo režim V86 / EV86 *)

Ak (eFlags.vm \u003d 1 a CR4.VME \u003d 1 a

(Int n) a IRB [n] \u003d 0)

Inak. Chránený režim.; (* Inštruovanie hardvéru, špeciálne situácie; int n softvér prerušuje: (1) chránený režim, (2) v86 s eV86 režimom 1 alebo 4 *)

Real-Addres-Mode:

Ak (((((((prerušenie * 4) + 3 presahuje segment pri prístupe k tabuľke VECTORS INTERRUPT INTERUPT) a potom #gp; Fi;

Ak (nie je miesto pre 6 bajtov v zásobníku), potom #ss; Fi;

EFlags.if \u003d 0; (* Resetujte vlajku prerušení *)

EFlags.tf \u003d 0; (* Reset Flag Traps *)

EFlags.ac \u003d 0; (* Resetujte príznaku režimu riadenia zarovnania *)

Cs \u003d ivt [prerušenie * 4] .Velecký;

Eip \u003d ivt [prerušenie * 4]. FFFSET a 0x0000FFFFH;

(* Pokračovanie práce v reálnom adresovaní ... *)

EV86-MODE: (* CR0.pe \u003d 1, EFLAGS.VM \u003d 1, CR4.VME \u003d 1, režim EV86 je prerušovaný program int n s IRB [n] \u003d 0 - MODE 3 alebo MODE 5 *)

Ak (v zásobníku úloh V86 neexistuje priestor pre 6 bajtov), \u200b\u200bpotom #ss (0); Fi;

tempflags \u003d vlajky;

tempflags.nt \u003d 0;

Potom eFlags.if \u003d 0; (* Resetujte vlajku povolenia prerušenia *)

tempflags.if \u003d eFlags.vif;

EFlags.vif \u003d 0; (* Resetovanie virtuálnej vlajky prerušení *)

EFlags.tf \u003d 0; (* Reset Flag Traps *)

Push (Tempflags);

(* Chybové kódy nie sú zapísané na zásobníku *)

Cs \u003d ivt_v86 [prerušenie * 4] .Velector; (* Tabuľka prerušenia vektorov IVT_V86 sa nachádza na začiatku adresného priestoru úlohy V86 *)

EIP \u003d IVT_V86 [prerušenie * 4] .offset a 0x0000ffffh; (* Starší 16-bitový register EIP sa resetuje *)

(* Pokračujúca práca v EV86 ... *)

Chránený režim: (* CR0.pe \u003d 1, hardvérové \u200b\u200bprerušenia, špeciálne situácie; int n softvér prerušuje v režime: (1) chránený režim, (2) v86 s eV86 režimom 1 alebo režimom 4 *)

Ak ((((((prerušenie * 8) + 7 nepatrí do IDT) TAN #GP (číslo prerušenia * 8 + 2 + EXT); Fi;

(* Ďalej len v parametroch kódu chybového kódu, termín +2 znamená nastavenie chybového kódu chybového kódu a termínov + ext - znamená nastavenie chybového kódu EXT v súlade s tým, či chyba spôsobila program prerušenia Ext \u003d 0 alebo externé ext \u003d 1 *)

AR Deskriptor Byte musí nastaviť prerušovaciu bránu, pasca brány alebo úloha bránu, inak #gp (prerušenie číslo * 8 + 2 + ext);

Ak (prerušenie softvéru alebo špeciálna situácia) (* Tí. Jeden z prípadov Int, Int 3, Int1, viazaný alebo do *)

Ak (CPL\u003e DPL Gateway)

#Gp (číslo prerušenia * 8 + 2); (* Cr0.pe \u003d 1, DPL Gateway< CPL, программное прерывание *)

Brána musí byť prítomná, inak #np (prerušenie * 8 + 2 + ext);

Ak (úlohy brány)

Potom goto. Brána.;

Ísť do. Pasce-alebo-int-brána; (* Cr0.pe \u003d 1, prerušenie alebo pasca brány *)

Trap alebo-int-brána: (* Chránený režim alebo režim V86 / EV86, pasca alebo prerušenie brány *)

Kontrola nového voliča CS zadaného v deskriptore brány a príslušný deskriptor z LDT alebo GDT:

Volič nesmie byť nula, inak, #gp (ext);

Index voliča by mal spadať do tabuľky deskriptorov, inak #gp (volič + ext);

Zvolená rukoväť musí byť kód deskriptora segmentu, inak #gp (volič + ext);

Segment musí byť prítomný (p \u003d 1), inak #np (volič + ext);

Ak (nekoordinovaný kódový segment) a (kódový segment DPL< CPL)

Ak eFlags.vm \u003d 0

Potom goto. Int-to-inter-v priv; (* Cr0.pe \u003d 1, eFlags.vm \u003d 0, prerušenie alebo pasca brána, nekonzistentný segment kódu, segment DPL kód< CPL *)

Inak (* eFlags.vm \u003d 1 *)

Ak (dpl nového segmentu kódu ≠ 0) potom #gp (segment voliča + ext); Fi;

Ísť do. Int-from-V86-Mode;(* Cr0.pe \u003d 1, eFlags.vm \u003d 1, prerušenie alebo pasca brána, segment DPL kód \u003d 0, CPL \u003d 3 *)

Inak. (* Cr0.pe \u003d 1, prerušenie alebo pasce brána, konzistentný segment kódu alebo nekonzistentný segment kódu s DPL \u003d CPL *)

Ak eFlags.vm \u003d 1 potom #gp (volič segmentu kódu + ext); Fi;

Ak ((zodpovedajúce zodpovedajúce) alebo (kódový segment DPL \u003d CPL))

Potom goto. Int-to-intra-priv; (* Cr0.pe \u003d 1, prerušenie alebo pasce brána, segment kódu DPL ≤ CPL pre konzistentný segment, kódový segment DPL \u003d CPL pre nekonzistentný segment *)

Inak #gp (volič kódu segmentu + ext); (* DPL\u003e CPL pre konzistentný segment alebo DPL ≠ CPL pre nekonzistentný segment *)

Int-to-Inter-Priv: (* Chránený režim, prerušenie alebo trap brána, nekonzistentný kódový segment, segment DPL kód< CPL *)

Ak (aktuálne TSS 32-bit)

TSSSTACKADDRESS \u003d (Nový kódový segment DPL * 8) + 4

Ak (((Tsstackaddress + 5)\u003e TSS limit) (* (TSSSSTACKADDRESS + 7)\u003e

Novinky \u003d [TSS + TSSSTACKADDRESS + 4] BASE; (* 2 bajty načítané *)

(* 4 bajty načítané *)

Inak. (* Aktuálne TSS 16-bit *)

TSSSTACKADDRESS \u003d (Nový segment kódu DPL * 4) + 2

Ak ((Tsstackaddress + 3)\u003e TSS limit) (* (Tsstactaddress + 4)\u003e TSS - pre niektoré modely procesorov *)

Potom #ts (volič aktuálnej TS + EXT);

NOVINKAP \u003d [TSS + TSSSTACKADDRESS BASE]; (* 2 bajty načítané *)

Novinky \u003d [TSS + TSSSTACKADDRESS + 2 BASE]; (* 2 bajty načítané *)

Volič RPL musí byť rovný DPL nového segmentu kódu, inak #ts (SS Selector + EXT);

DPL diskusného segmentu sa musí rovnať DPL nového segmentu kódu, inak #ts (SS Selector + EXT);

Ak (32-bitová brána)

Potom by sa mal uskutočniť nový zásobník pre 20 bajtov (24 bajtov, ak je kód chyby), inak #ss (ext)

Inak by sa mal prebiehať nový zásobník pre 10 bajtov (12 bajtov, ak existuje kód chyby), inak #ss (ext)

SS: ESP \u003d TSS (NOVINKY: NOVINKAP); (* Stiahnite si nové hodnoty SS a ESP z TSS *)

Ak (32-bitová brána)

Potom.

Else CS: IP \u003d brána (volič: offset);

Stiahnite si deskriptor SS v skrytej časti registra SS;

Ak (32-bitová brána)

Tlačiť (dlhý ukazovateľ na starý zásobník - SS: ESP);

Tlačiť (dlhý ukazovateľ na návratový bod - CS: EIP); (* 3 slová sú doplnené na 4 *)

Zatlačte (chybový kód);

Tlačiť (dlhý ukazovateľ na starý zásobník - SS: SP); (* 2 slová *)

Tlačiť (dlhý ukazovateľ na návratový bod - CS: IP); (* 2 slová *)

Zatlačte (chybový kód);

CPL \u003d DPL nového segmentu kódu;

Ak (prerušenie brány) potom eFLAGS.IF \u003d 0 FI; (* Resetujte príznak prerušenia *)

EFLAGS.RF \u003d 0;

(* Pokračovanie práce v chránenom režime na úrovni s veľkými privilégiami ... *)

Int-from-V86-Mode: (* V86 / EV86 režim, prerušenie alebo Trap brána, DPL \u003d 0, CPL \u003d 3 *)

(* Aktuálne TSS je vždy 32-bitový režim v86 *)

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

Potom #ts (volič aktuálnej TS + EXT);

NOVINKY \u003d [BASE TSS + 8]; (* 2 bajty načítané *)

NOVINKAP \u003d [BASE TSS + 4]; (* 4 bajty načítané *)

Skontrolujte volič nového segmentu zásobníkov správ a príslušného deskriptora z LDT alebo GDT:

Volič nesmie byť nula, inak #ts (ext);

Index voliča by mal spadať do tabuľky deskriptora, inak #ts (SS Selector + EXT);

Volič RPL by mal byť nula, inak #ts (SS Selector + EXT);

DPL diskusného segmentu musí byť nula, inak #ts (ss volič + ext);

Deskriptor musí mať formát deskriptora deskriptora údajov povolený na nahrávanie (w \u003d 1), inak #ts (ss volič + ext);

Segment musí byť prítomný (p \u003d 1), inak #ss (ss volič + ext);

Ak (32-bitová brána)

Nový zásobník by sa mal uskutočniť pre 36 bajtov (40 bajtov, ak existuje kód chyby), inak #ss (ext)

Nový indikátor inštrukcie by mal spadať do nového segmentu kódu, inak #gp (ext); (* Ukazovateľ inštrukcií je určený hodnotou poľa Offset z deskriptora brány *)

Tempeflags \u003d eFlags;

EFlags.vm \u003d 0; (* Procesor vychádza z režimu V86 na proces prerušenia v chránenom režime *)

Ak (prerušovaná brána)

Potom eFlags.if \u003d 0;

Cpl \u003d 0; (* Prepnúť na úroveň nuly privilégium *)

SS: ESP \u003d TSS (NOVINKY: NOVINKAP); (* Stiahnite si hodnoty SS0 a ESP0 z TSS *)

Tlačiť (gs);

Tlačiť (FS); (* Rozširuje sa na dve slová *)

Tlačiť (ds); (* Rozširuje sa na dve slová *)

Push (es); (* Rozširuje sa na dve slová *)

Gs \u003d 0; (* Segmentové registre sa resetujú. Je neprijateľné, aby sa následné používanie nulových voličov v bezpečnom režime *)

Tlačiť (temps); (* Rozširuje sa na dve slová *)

Push (tempeflags);

Tlačiť (cs); (* Rozširuje sa na dve slová *)

Zatlačte (chybový kód); (* Ak je prítomné, 4 bajty *)

Cs: EIP \u003d brána (volič: offset); (* Stiahnutie voliča: Offset z 32-bitovej brány deskriptor *)

Inak (* 16-bitová brána *)

Nový zásobník sa musí uskutočniť pre 18 bajtov (20 bajtov, ak existuje kód chyby), inak #ss (ext)

(* Úspora v stohu 16-bitových registrov sa vyskytuje podobne ako 32-bitová brána *)

(* Návrat z prerušenia s príkazom IRET späť do režimu V86 z 16-bitového segmentu nebude možné, pretože príznak VM nebude uložený v zásobníku a nebude sa obnoviť z obrazu EFLAGS pri návrate * )

(* Pokračovanie práce v chránenom režime na nulovej úrovni privilégií ... *)

Int-to-intra-priv: (* CR0.pe \u003d 1, DPL \u003d CPL alebo konzistentný segment s DPL ≤ CPL *)

Ak (32-bitová brána)

Potom by sa mal prebiehať nový zásobník pre 12 bajtov (16 bajtov, ak je kód chyby), inak #ss (ext)

Inak by sa nový stoh mal prebiehať pre 6 bajtov (8 bajtov, ak je kód chyby), inak #ss (ext)

Nový indikátor inštrukcie by mal spadať do nového segmentu kódu, inak #gp (ext);

Ak (32-bitová brána)

Tlačiť (dlhý ukazovateľ na návratový bod); (* 3 slová sú doplnené na 4 *)

Cs: EIP \u003d brána (volič: offset); (* Stiahnutie voliča: Offset z 32-bitovej brány deskriptor *)

Zatlačte (chybový kód); (* Ak je prítomné, 4 bajty *)

Tlačiť (dlhý ukazovateľ na návratový bod); (* 2 slová *)

CS: IP \u003d brána (volič: offset); (* Sťahovanie sťahovania: Offset z 16-bitovej deskriptora brány *)

Zatlačte (chybový kód); (* Ak je prítomné, 2 bajty *)

Stiahnite si deskriptor CS v skrytej časti registra CS;

Ak (prerušenie brány) potom eflags.if \u003d 0; Fi;

(* Pokračovanie práce v chránenom režime bez zmeny úrovne privilégií ... *)

Úloha-brána: (* Cr0.pe \u003d 1, úloha brána *)

Skontrolujte výber TSS z úlohy Gateway Popis:

Volič musí nastaviť GDT (bit Ti \u003d 0), inak #gp (TSS volič + ext);

Index voliča by mal spadať do tabuľky GDT, inak #gp (TSS volič + ext);

Kontrola zodpovedajúceho deskriptora TSS zodpovedajúceho zvoleného voliča:

Deskriptor TSS musí mať typ bezplatných TSS (TYT.B \u003d 0), inak #gp (TSS volič + ext);

TS musia byť prítomné (p \u003d 1), inak #np (volič TSS + ext);

Spínacie úlohy (s prílohou) v TSS; (* Tu "s prílohou" znamená, že pri inicializácii kontextu novej úlohy bude nastavená vlajkou EFLAGS.NT \u003d 1 a úloha TSS Selector (stará) sa skopíruje v segmente TSS (starý) Segment - pozri adresovanie a multitasking: znamená podporu multisasca *)

Ak (prerušenie je špeciálna situácia s kódom chyby)

Stoh musí byť miestom pre kód chyby, inak #ss (ext);

Zatlačte (chybový kód);

Ukazovateľ inštrukcií EIP by mal spadať do segmentu CS, inak #gp (ext);

(* Načítanie kontextu novej úlohy je sprevádzané dodatočnými kontrolami, ako je opísané v časti Addressing a Multitasking: Podpora multisadality *)

(* Pokračovanie práce v kontexte novej úlohy ... *)

Osobitné situácie chráneného režimu: \\ t

Int 3.Ale aj po prijatí akéhokoľvek externého prerušenia alebo výroby osobitnej situácie. Trocha Ext. V kóde o chybe externého prerušenia).

  • deskriptor vektor (Index) prerušenia nie je v tabuľke deskriptorov prerušenia (IDT);
  • deskriptor vektor (Index) prerušenia, nie je deskriptor chyby brány, prerušenie brány alebo úloha brány;
  • existuje prerušenie softvéru alebo špeciálna situácia softvéru (to znamená jeden z prípadov: Int N, Int 3, Int0N, viazaný alebo do) a súčasne súčasná úroveň privilégií (CPL) Úlohy viac Úrovne privilégií(DPL) deskriptor brány Z tabuľky IDT -
  • segmentový volič v príslušnej spracovanej vektor (Index) prerušenia deskriptora brány TRAP, prerušená brána alebo úloha brána je nulový volič;
  • výber segmentu segmentového segmentu trap brány alebo deskriptor prerušenia brány nepatrí do príslušnej tabuľky deskriptorov;
  • index voliča TSS z príslušného prerušenia deskriptora úlohy brány nespadá globálna tabuľka deskriptorov (GDT);
  • deskriptor Nový segment kódu nie je deskriptor segmentu kódu;
  • (DPL) Nový segment koordinovaného kódu privilégium aktuálnej úrovne (CPL) úlohy -
  • Úroveň deskriptora privilégií (DPL) nového segmentu nekonzistentného kódu nie je rovnaký súčasná úroveň privilégií (CPL) úlohy -
  • výber TSS z príslušného prerušenia deskriptora úlohy brány označuje miestne deskriptory tabuľky (LDT);
  • deskriptor TSS novej úlohy je uvedený ako zaneprázdnený- TYPT.B ≠ 1.
  • adresa, na ktorej by sa mala čítať nová hodnota stohový ukazovateľ (SS: ESP), presahuje segment TSS;
  • výber nového segmentu zásobníka je nulový volič;
  • index voliča nového segmentu zásobníka nespadá do príslušnej tabuľky deskriptorov;
  • požadovaná úroveň privilégií (RPL) Výber nového segmentu zásobníka nie je rovný (DPL) Nový segment kódu -
  • Úroveň deskriptora privilégií (DPL) nového segmentu zásobníka nie je rovnaký Úroveň deskriptora privilégií (DPL) Nový segment kódu -
  • nový segment zásobníka nie je k dispozícii dátový segment na nahrávanie -
  • zodpovedajúce prerušenie deskriptora Trap Gateway, prerušenie brány, úloha brána alebo deskriptor TSS je označený ako bez sprievodu (Bit Phisors je resetovaný);
  • nový segment kódu nie je prítomný (bit P. Deskriptor segmentu sa resetuje).
  • pri písaní do zásobníka (vrátane nového zásobníka, ak je spínacia zácica) adresy Return, stohový ukazovateľ, vlajky alebo kód chyby je vhodný pre prípustnú hranicu segmentu zásobníka;
  • nový segment zásobníka nie je prítomný (Bit P segment deskriptor sa resetuje).

Osobitné situácie skutočného režimu adresovania:

Zoznam prezentovaných špeciálnych situácií tu charakterizuje správanie procesora nielen pri vykonávaní príkazu Int 3.Ale aj po prijatí akéhokoľvek externého prerušenia alebo výroby osobitnej situácie.

Špeciálne situácie režimu V86:

Zoznam prezentovaných špeciálnych situácií tu charakterizuje správanie procesora nielen pri vykonávaní príkazu Int 3.Ale aj po prijatí akéhokoľvek externého prerušenia alebo výroby osobitnej situácie. Trocha Ext. V chybovom kóde sa používa na označenie externého vzťahu k prerušenému programu udalosti (

Všetky funkcie DOS sú nazývané prerušením 21h (v desatinnom zápise 33). Prvá verzia DOS obsahovala 42 funkcií. V druhej, 33 ďalších funkcií sa k nim pridáva, ktoré sú uložené vo všetkých nasledujúcich verziách. Voľba špecifickej funkcie sa vykonáva zaznamenaním príslušného čísla do registra AH.

Funkcia 02: Výstupný jeden symbol na obrazovke

Na výstup jedného znaku na použitom obrazovke počítača

21H Prerušenie funkcie 02:

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

Výstupný symbol je zvýraznený v polohe kurzora (bez ohľadu na to, čo sa zaznamená), po ktorom sa kurzor pohybuje do jednej pozície doprava. Ak bol kurzor na konci reťazca obrazovky, potom sa presunie na začiatok nasledujúceho riadku, a ak bol kurzor na konci posledného riadku obrazovky, obsah obrazovky posúva jeden riadok smerom nahor a prázdny String sa zobrazí v dolnej časti a kurzor je nainštalovaný.

Symboly s kódmi 7, 8, 9, 10 (0AH) a 13 (0HDH) sa vykonávajú špeciálnym spôsobom. Symbol s kódom 7 (Bell, Call) na obrazovke nie je zvýraznený (a kurzor sa nezmení) a príčiny zvukový signál. Symbol s kódom 8 (Backspase, krok späť) Vráti kurzor na jednu polohu doľava, pokiaľ to nebol v ľavej línii reťazca. Symbol s kódom 9 (karta, tabs) vytesňuje kurzor doprava do najbližšej polohy, viacnásobný 8. Symbol s kódom 10 (riadok, riadok preklady) presunie kurzor na nasledujúci riadok riadkov, ktorý ho opúšťa v rovnakom stĺpca. Symbol s kódom 13 (Carrige Returte, návrat vozíka) Nastaví kurzor na začiatok aktuálnej čiary; Záver v rade znakov s kódmi 13 a 10 znamená prekladanie kurzora na začiatok nasledujúceho riadku.

Funkcia 9: Zobrazenie reťazca na obrazovke displeja

Ak chcete zobraziť reťazec (symbolové sekvencie), môžete, samozrejme, použiť funkciu 02, ale môže byť vykonaná na jednom príjmoch pomocou funkcie interruntu 21H 21:

DS: DX: \u003d Začiatočná riadková adresa

Pred odkazom na túto funkciu musí byť počet pamäťových segmentov umiestnený v registri DS, v ktorom je výstupný riadok umiestnený a v registri DX - rezanie riadkov vo vnútri tohto segmentu. Súčasne na konci riadku by mal byť symbol $ (kód 24h), ktorý slúži ako znak na konci riadku a nie je zobrazený.

Hoci táto funkcia môže byť veľa vhodnejšie pre funkcie Zberný výstup na obrazovke (funkcia 2 a 6), má nevýhodu, že ako obmedzovač reťazca sa používa úplne obyčajný $ symbol. Toto je ďalšia bočná kompatibilita produktu s CP / M.

Advanced DOS operačný systém funguje ako reťazec obmedzovač na použitie CHR $ (0). To vyhovuje dohodám prijatým v operačnom systéme UNIX a programovacom jazyku SI.

Neexistuje žiadna taká vec medzi funkciami DOS, ktorá zobrazuje čísla. Takáto operácia, ak je to potrebné, musí byť implementovaná na základe zvážených funkcií.

4CH funkcia: Dokončenie programu

Po ukončení všetkých svojich akcií je program povinný vrátiť správu operačného systému, aby užívateľ mohol pokračovať v práci na PC. Takáto náhrada je implementovaná funkciou 21H prerušenia, ktorá je umiestnená na konci programu:

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

Každý program, všeobecne hovorí, je povinný úspešne alebo nie dokončiť svoju prácu. Faktom je, že akýkoľvek program sa volá z nejakého iného programu (napríklad z operačného systému), a niekedy sa nazýva program, ktorý riadne pokračuje v práci, musíte vedieť, či splnil tento program, alebo to fungovalo s chyba. Takéto informácie sa prenášajú ako Kódex ukončenia programu (niektoré celé číslo), ktoré by mali byť nula, ak program funguje správne, a nenulové (čo je špecificky stanovené v každom prípade) inak. (Kód dokončenia programu sa môžete naučiť pomocou funkcie 4DH prerušenia 21h.) Tento kód bude potrebný alebo nie, program ho musí ešte dávať.

Čo je to assembler

Assembler je nízkonákladový programovací jazyk. Pre každý procesor je assembler. Programovanie na assembler, ktorý pracujete priamo s počítačovým nástrojom. Zdrojový text v jazyku assembler sa skladá z príkazov (Mnemonics), ktorý po kompilácii sa po kompripozícii konvertujú na kódové kódy príkazov procesora.

Vývoj programov na assembler je veľmi ťažká vec. Namiesto času stráveného času dostanete efektívny program. Programy assembler sú napísané, keď je dôležitý každý cyklus procesora. V Assembleri dávate špecifické príkazy procesoru a akémukoľvek extra odpadu. To sa dosahuje vysokou rýchlosťou vášho programu.

Aby ste kompetentne používali assembler, musíte poznať model softvéru mikroprocesora. Z hľadiska programátora sa systém mikroprocesora skladá z:

  1. Mikroprocesor
  2. Pamäť
  3. I / O zariadenia.

Softvérový model je dobre opísaný v literatúre.

Syntax Assembler

Všeobecný formát reťazca programu na assembler

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

Tagy. Štítok môže pozostávať z znakov a adhéznych znakov. Značky sa používajú v podmienených a bezpodmienečných prechodových operáciách.

Operátorské pole. Toto pole obsahuje tím mnemonic. Napríklad, mnemonica mOV.

Operand. Operandy môžu byť prítomné len vtedy, ak je prevádzkovateľ prítomný (pole operátora). Operandy nemusia byť, a možno niekoľko. Operands môžu byť údaje, ktoré potrebujete na vykonanie niektorých akcií (dopredu, fold, atď.).

Pole Komentár. Komentár je potrebný na verbálnu podporu programu. Všetko, čo je za symbolom ; Považuje sa za komentár.

Prvý program v jazyku Assembler

Tento článok bude používať assembler pre procesor I80X86 a používa sa nasledujúci softvér:

  • Tash - Borland Turbo Assembler - kompilátor
  • TLINK - BORLAND TURBO Linker - Komunikácia Editor (linker)

Byť betón, TASM 2.0.

Tradíciou, náš prvý program stiahne reťazec "Hello World!" na obrazovke.

Súbor vzorky.

MODEL MALÉHO; Pamäťový model.stack 100h; Nastavenie veľkosti zásobníka.DATA; Začiatok územného segmentu programu Helomsg DB "Hello World!", 13.10, "$" .code; Začiatok segmentu kódu AX AX, @ dáta; Adresa dátového segmentu odošleme na register AX MOV DS, AX; Inštalácia registra DS do segmentu údajov MOV AH; DOS riadok výstup funkcie na obrazovke MOV DX, Offset Helomsg; Špecifikujeme posun na začiatok riadku INT 21H; Zobrazí sa reťazec, 4c00h; DOS Funkcia Exit z programu INT 21H; Koniec

Ako si možno všimnete, že program je rozdelený na segmenty: dátový segment, segment kódu a je tu ďalší segment zásobníka.

Zvážte všetko v poriadku.

Smernica.Model Small Určuje pamäťový model. Malý model je 1 segment pre kód, 1 segment pre dáta a zásobník, tj Údaje a zásobník sú v rovnakom segmente. Existujú aj iné pamäťové modely, napríklad: drobné, stredné, kompaktné. V závislosti od modelu pamäte, ktorý ste vybrali, vaše programy sa môžu prekrývať alebo môžu mať samostatné segmenty v pamäti.

Smernica .Stack 100H Nastaví veľkosť zásobníka. Stack je potrebný na uloženie niektorých informácií s jeho následným obnovením. Konkrétne sa stoh používa počas prerušení. V tomto prípade je obsah registra vlajky vlajky, registra CS a IP registra stohovanie. Ďalej existuje program prerušenia a potom je obnovená hodnotami týchto registrov.

  • Flags Flags Register obsahuje príznaky, ktoré sú vytvorené po vykonaní príkazu na procesor.
  • CS Register (segment kódu) obsahuje adresu segmentu kódu.
  • Register IP (inštrukčný ukazovateľ) je príkazový ukazovateľ. Obsahuje adresu príkazu, ktorý musí byť dokončený ďalší (adresa vzhľadom na segment CS Code).

Viac detailný popis Vstup do rámca jednoduchého článku.

Smernica.Data určuje začiatok segmentu údajov vášho programu. Segment údajov definuje "premenné" t.j. V požadovaných údajoch sa nachádza redundancia pamäte. Potom.Data ide reťazec
Helómsg db "Hello World!", 13.10, "$"

Tu Helmsg je symbolický názov, ktorý zodpovedá začiatku riadku "Hello World!" (bez úvodzoviek). To znamená, že je to adresa prvého symbolu nášho reťazca vzhľadom na segment údajov. Smernica DB (Define Byte) definuje oblasť pamäte dostupnej v obtoku. 13.10 - Symbolové kódy Nový riadok A návrat vozíka a $ symbol je potrebný na správnu prevádzku funkcie DOS 09h. Takže náš reťazec bude zaberať do pamäte 15 bajtov.

Smernica. Kód Určuje začiatok segmentu kódu (segment CS - Code) programu. Potom riadky programu obsahujúci mnemonics tímov.

Poviem vám o tíme MOV.

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

Príkaz príkazu - odosielanie. Postúpi obsah zdroja do prijímača. Prenos môže byť registračným registrom, registráciou, registráciou pamäte, ale nie je tu žiadna prenosová pamäť. Všetko prechádza cez registre procesora.

Ak chcete pracovať s údajmi, musíte nakonfigurovať register údajov. Nastavenie je, že zaznamenávame adresu dát @data v registri DS (segment údajov). Priamo zaznamenajte adresu v tomto registri nie je možná - to je architektúra, takže používame register AX. V sekóne, napíšeme adresu segmentu kódu

a potom posielame obsah registra AX do registra DS.

Po tom, register DS bude obsahovať adresu segmentu údajov. Adresa DS: 0000H bude obsahovať symbol H. Predpokladám, že viete o segmentoch a kompenzáciách.

Adresa sa skladá z dvoch zložiek<Сегмент>:<Смещение>Tam, kde segment je 2 bajty a offset-2 bajty. Ukazuje 4 bajty na prístup k ľubovoľnému umiestneniu pamäte.

mOV AH, 09H
MOV DX, Offset Helomsg
Int 21h.

Tu sme v AH Register, napíšte číslo 09H - číslo 21. funkcie prerušenia, ktorá zobrazuje reťazec na obrazovke.

V ďalšom riadku píšeme adresu (rozpaky) na začiatok nášho riadku v registri DX.

Ďalej nazývame prerušenie 21h, je prerušenie funkcií DOS. Prerušenie - Po prerušení programu sa začne program prerušenia a program prerušenia. Podľa čísla prerušenia je určená adresa podprogramu DOS, ktorá zobrazuje znakový reťazec na obrazovku.

Pravdepodobne budete mať otázku: Prečo píšeme číslo funkcie 09h v AH Register? A prečo je ofset s reťazcom napísaným do registra DX?
Odpoveď je jednoduchá: Pre každú funkciu sú definované špecifické registre, ktoré obsahujú vstupné údaje pre túto funkciu. Pozrite sa, ktoré registre sú potrebné špecifické funkcie, ktoré môžete v pomoci "e.

cestovná sekera, 4c00h
Int 21h.

mOV AX, 4C00H - Posielame funkčné číslo do registra AX. Funkcia 4c00h - Ukončite program.

iNT 21H - Vykonajte prerušenie (skutočne vyjde)

koniec je koniec programu.

Po ukončenej smernici, kompilátor ignoruje všetko, takže môžete napísať všetko, čokoľvek :)

Ak čítate na koniec, potom ste hrdina!

Maiko G.V. Assembler pre IBM PC: - m.: "Business Inform", "Sirin" 1999 - 212 p.



Páči sa vám článok? Zdieľaj to