Intel Assembler

Ebben az 5 részből álló cikkben az Intel 8086-os processzor utasításkészletével, regisztereivel, címzési módjaival, a Turbo Assembler formai szabályaival és a Turbo Pascal fejlesztőkörnyezethez való kapcsolódással ismertetem meg az olvasót.

1. i8086 utasítások

AAA    Két ASCII számjegy összeadása után az eredményből al és ah

      regiszterekben két pakolatlan BCD számot hoz létre.

      Módosított flag-ek: cf, af.

      Órajel ciklus: 4.

AAS    Két ASCII számjegy kivonása után az eredményt az előző utasításhoz

      hasonlóan BCD formátumra hozza.

      Módosított flag-ek: cf, af.

      Órajel ciklus: 4.

AAD    BDC számok előkészítése osztáshoz úgy, hogy az ah, al regiszterekben

      lévő pakolatlan BCD szám nagyobbik helyiértékét (ah-t) megszorozza 0ah-

      val és hozzáadja al-hez. Így a szám hexadecimális alakját kapjuk.

      Módosított flag-ek: sf, zf, pf.

      Órajel ciklus: 60.

AAM   az AAD utasítás fordítottja, ez a szorzás után kapott hexadecimális

      számot alakítja át pakolatlan BCD számmá.

      Módosított flag-ek: sf, zf, pf.

      Órajel ciklus: 80.

DAA    Két BCD szám összeadása után az eredményt BCD alakra igazítja.

      Módosított flag-ek: sf, zf, af, pf, cf.

      Órajel ciklus: 4.

DAS    Két BCD szám kivonása után az eredményt BCD alakra igazítja.

      Módosított flag-ek: sf, zf, af, pf, cf.

      Órajel ciklus: 4.

DEC    Operandus értékének csökkentése eggyel.

      Módosított flag-ek: of, sf, zf, af, pf.

      Órajel ciklus: 2-13.

INC     Operandus értékének növelése eggyel.

      Módosított flag-ek: of, sf, zf, af, pf.

      Órajel ciklus: 2-23.

ADD    A második operandus értékét hozzáadja az elsőhöz.

      Módosított flag-ek: of, sf, zf, af, pf, cf.

      Órajel ciklus: 3-25.

SUB    A második operandus értékét kivonja az elsőből.

      Módosított flag-ek: of, sf, zf, af, pf, cf.

      Órajel ciklus: 3-37.

ADC    Az első operandushoz hozzáadja a másodikat és a carry flag tartalmát.

      Módosított flag-ek: of, sf, zf, af, pf, cf.

      Órajel ciklus: 3-25.

SBB     Az első operandus értékéből kivonja a második operandus értékét és a

      carry bit tartalmát.

      Módosított flag-ek: of, sf, zf, af, pf, cf.

      Órajel ciklus: 3-37.

DIV     Előjel nélküli osztás. 8 bites művelet esetén az osztandó számot az ax

      regiszter tartalmazza, az osztót pedig a bl, és az eredményt al-be, a

      maradékot ah-ba kapjuk. 16 bites művelet esetén az osztandót dx:ax

      tartalmazza, az osztót pedig a bx regiszter, az eredményt az ax, a

      maradékot a dx regiszterben kapjuk.

      Módosított flag-ek: nem meghatározott.

      Órajel ciklus: 0-162.

MUL   Előjel nélküli szorzás.

      Módosított flag-ek: of, cf.

      Órajel ciklus: 70-143.

IDIV    Előjeles osztás. Az előjel az adat legmagasabb helyiértékű bitje.

       Módosított flag-ek: nem meghatározott.

       Órajel ciklus: 101-194

IMUL  Előjeles szorzás. Az előjel az adat legmagasabb helyiértékű bitje.

       Módosított flag-ek: of, cf.

       Órajel ciklus: 80-164.

MOV   Adatmozgatás. Az első operandus tartalmát a másodikba írja.

      Módosított flag-ek: nem befolyásolja a flag-ek állását.

      Órajel ciklus: 2-26.

MOVSx (MOVSB, MOVSW)

         DS:SI által címzett byte-ot, illetve word-öt ES:DI címre írja majd

        Direction flag értékétől függően növeli (d=0), illetve csökkenti

        (d=1) di és si regisztereket byte-os műveletnél eggyel, word-ösnél

        kettővel.

        Módosított flag-ek: nem befolyásolja a flag-ek állását.

        Órajel ciklus: 9+17(25)/rep.

STOSx (STOSB,STOSW)

         al és ax tartalmát ES:DI címre írja, majd d flag-től függően növeli,

        illetve csökkenti di értékét.

        Módosított flag-ek: nem befolyásolja a flag-ek állását.

        Órajel ciklus: 9+10(14)/rep.

LODSx (LODSB, LODSW)

         DS:SI által címzett byte vagy word tartalmát al és ah regiszterbe

        tölti, és az si értékét a d flag-től függően változtatja.

        Módosított flag-ek: nem befolyásolja a flag-ek állását.

        Órajel ciklus: 9+13(17)/rep.

LEA     A kijelölt operandusba tölti a forrásoperandus offsetcímét, működése

      megegyezik a MOV reg, offset cím utasítással.

      Módosított flag-ek: nem befolyásolja a flag-ek állását.

      Órajel ciklus: 8-14.

LDS     Egy négy byte-os memória operandus első és második byte-ja kerül a

      megadott regiszterbe, 3. 4. byte-ja pedig a ds regiszterbe.

      Módosított flag-ek: nem befolyásolja a flag-ek állását.

      Órajel ciklus: 30-36.

LES     Egy négy byte-os memória operandus első és második byte-ja kerül a

      megadott regiszterbe, 3. és 4. byte-ja pedig az es regiszterbe.

      Módosított flag-ek: nem befolyásolja a flag-ek állását.

      Órajel ciklus: 30-36.

XLAT  A bx+al címen lévő adatot tölti al regiszterbe. Segítségével könnyedén

       olvashatunk ki egy maximum 256 byte hosszú táblázatból egy adatot: bx

       regiszterbe beállítjuk a táblázat kezdőcímét, majd al-be a kiolvasandó

       elem sorszámát. Az utasítás végrehajtása után a kiválasztott elem

       értéke al-ben lesz.

       Módosított flag-ek: nem befolyásolja a flag-ek állását.

       Órajel ciklus: 11.

XCHG Megcseréli az első és a második operandus értékét.

       Módosított flag-ek: nem befolyásolja a flag-ek állását.

       Órajel ciklus: 3-37.

LAHF  A flag regisztert az ah regiszterbe másolja.

       Módosított flag-ek: nem befolyásolja a flag-ek állását.

       Órajel ciklus: 4.

SAHF  Az ah regiszter értékét a flag regiszterbe másolja.

       Módosított flag-ek: zf, sf, af, pf, cf.

       Órajel ciklus: 4.

CBW   Az ah regisztert feltölti az al regiszter felső bitjével. Ez a művelet

      főként előjeles műveletek végzésénél használatos.

      Módosított flag-ek: nem befolyásolja a flag-ek állását.

      Órajel ciklus: 2.

CWD   Az ax regisztert (word-öt) dupla word-dé alakítja DX:AX-be.

      Módosított flag-ek: nem befolyásolja a flag-ek állását.

      Órajel ciklus: 5.

CMP   Két operandus összehasonlítása egy látszólagosan elvégzett kivonási

      eljárás segítségével. A flag regiszter egyes bitjeit ennek megfelelően

      állítja be.

      Módosított flag-ek: of, sf, zf, af, pf, cf.

      Órajel ciklus: 3-14.

CMPSx (CMPSB, CMPSW)

         DS:SI és ES:DI által mutatott memóriarekesz tartalmának

        összehasonlítása. Az si és di regisztereket d flag-tőlfüggően növeli

        vagy csökkenti.

        Módosított flag-ek: cf, af, pf, of, sf, zf.

        Órajel ciklus: 9+22(30)/rep.

SCASx (SCASB, SCASW)

         Az al és az ax tartalmát összehasonlítja ES:DI által mutatott

        memóriarekesz tartalmával, és a jelzőbiteket ennek megfelelően

        állítja be. Az utasítás segítségével könnyen megtalálható egy adat

        előfordulási helye.

        Módosított flag-ek: of, sf, zf, af, pf, cf.

        Órajel ciklus: 9+15(19)/rep.

TEST   Hatása azonos az AND-del, de a regiszterek tartalmát nem változtatja

       meg, csak a fleg-et.

       Módosított flag-ek: of, sf, zf, pf, cf.

       Órajel ciklus: 3-25.

CLC    Az átviteli jelzőbitet nullára állítja.

      Módosított flag-ek: cf.

      Órajel ciklus: 2.

STC     Az átviteli jelzőbitet 1-re állítja.

      Módosított flag-ek: cf.

      Órajel ciklus: 2.

CMC   Komplementálja a carry flag-et.

      Módosított flag-ek: cf.

      Órajel ciklus: 2.

CLD    Az irányjelző flag-et nullára állítja.

      Módosított flag-ek: df.

      Órajel ciklus: 2.

STD     Az irányjelző flag-et 1-re állítja.

      Módosított flag-ek: df.

      Órajel ciklus: 2.

CLI      A hardware megszakításkérések fogadásának tiltása (kivétel az NMI).

      Módosított flag-ek: if.

      Órajel ciklus: 2.

STI      A hardware megszakítások engedélyezése.

      Módosított flag-ek: if.

      Órajel ciklus: 2.

IN        Adott porton lévő adat beolvasása. Az olvasás történhet al vagy ax

     regiszterbe, illetve 8 és 16 bites portcímről. Utóbbi esetben a címet dx

     regiszterbe kell tölteni, egyébként számmal kiírható.

     Módosított flag-ek: nem befolyásolja a flag-ek állását.

     Órajel ciklus: 8-14.

INSx (INSB, INSW)

        Byte vagy word beolvasása dx által mutatot portról ES:DI címre. Növeli

       vagy csökkenti di értékét d flag-től függően.

       Módosított flag-ek: nem befolyásolja a flag-ek állását.

       Órajel ciklus: 9+14(17)/rep.

OUT    Adott portra adat kiírása. Az írás történhet al vagy ax regiszterbe,

      illetve 8 és 16 bites portcímre. Utóbbi esetben a címet dx

      regiszterbe kell tölteni, egyébként számmal kiírható.

      Módosított flag-ek: nem befolyásolja a flag-ek állását.

      Órajel ciklus: 8-14.

OUTSx (OUTSB, OUTSW)

         DS:SI által címzett adat küldése a kijelölt porton keresztül. Az si

        regiszter növelése vagy csökkentése.

        Módosított flag-ek: nem befolyásolja a flag-ek állását.

        Órajel ciklus: 9+14(17)/rep.

PUSH  Csökkenti sp értékét kettővel, és a kiválasztott 16 bites regisztert

       a verem tetejére írja (sp mindig az utoljára beírt adatra mutat).

       Módosított flag-ek: nem befolyásolja a flag-ek állását.

       Órajel ciklus: 15-36.

PUSHF

         A flag regiszter tartalmát a sctack-re írja.

        Módosított flag-ek: nem befolyásolja a flag-ek állását.

        Órajel ciklus: 14.

POP    Kiolvassa az sp által mutatot értéket, és a kiválasztott regiszterbe

      tölti, majd növeli sp értékét kettővel.

      Módosított flag-ek: nem befolyásolja a flag-ek állását.

      Órajel ciklus: 12-37.

POPF  A veremről leemelt értéket a flag regiszterbe tölti, majd növeli sp

       értékét kettővel.

       Módosított flag-ek: of, df, if, tf, sf, zf, af, pf, cf.

       Órajel ciklus: 12.

JMP     Feltétel nélküli vezérlésátadás a megadott címre (közeli: near, illetve

      távoli: far).

      Módosított flag-ek: nem befolyásolja a flag-ek állását.

      Órajel ciklus: 11-24.

JA        Ugrás a megadott címre, ha előjel nélkül nagyobb.

     Módosított flag-ek: nem befolyásolja a flag-ek állását.

     Órajel ciklus: 4-16.

JNA     Ugrás a megadott címre, ha előjel nélkül kisebb vagy egyenlő.

      Módosított flag-ek: nem befolyásolja a flag-ek állását.

      Órajel ciklus: 4-16.

JNC     Ugrás a megadott címre, ha előjel nélkül nagyobb vagy elgyenlő.

      Módosított flag-ek: nem befolyásolja a flag-ek állását.

      Órajel ciklus: 4-16.

JC        Ugrás a megadott címre, ha előjel nélkül kisebb.

     Módosított flag-ek: nem befolyásolja a flag-ek állását.

     Órajel ciklus: 4-16.

JZ        Ugrás a megadott címre, ha elgyenlő.

     Módosított flag-ek: nem befolyásolja a flag-ek állását.

     Órajel ciklus: 4-16.

JNZ     Ugrás a megadott címre, ha nem elgyenlő.

      Módosított flag-ek: nem befolyásolja a flag-ek állását.

      Órajel ciklus: 4-16.

JG        Ugrás a megadott címre, ha előjelesen nagyobb.

     Módosított flag-ek: nem befolyásolja a flag-ek állását.

     Órajel ciklus: 4-16.

JNG - Ugrás a megadott címre, ha előjelesen kisebb vagy egyenlő.

      Módosított flag-ek: nem befolyásolja a flag-ek állását.

      Órajel ciklus: 4-16.

JGE     Ugrás a megadott címre, ha előjelesen nagyobb vagy egyenlő.

      Módosított flag-ek: nem befolyásolja a flag-ek állását.

      Órajel ciklus: 4-16.

JNGE  Ugrás a megadott címre, ha előjelesen kisebb.

       Módosított flag-ek: nem befolyásolja a flag-ek állását.

       Órajel ciklus: 4-16.

LOOP Csökkenti cx értékét, és ha nem érte el a nullát, akkor ugrik a

       megadott címre. Segítségével cx hosszúságú ciklust készíthetünk.

       Módosított flag-ek: nem befolyásolja a flag-ek állását.

       Órajel ciklus: 5-17.

LOOPZ

         A ciklus addig tart, amíg cx el nem éri a nullát vagy z bit nullára

        nem vált.

        Módosított flag-ek: nem befolyásolja a flag-ek állását.

        Órajel ciklus: 6-18.

LOOPNZ

          A ciklus addig tart, amíg z bit nulla és cx nem nulla.

         Módosított flag-ek: nem befolyásolja a flag-ek állását.

         Órajel ciklus: 6-18.

REP     A karakterlánc műveletek ismétlése, amíg cx nem nulla. Csökkenti cx

      értékét eggyel.

      Módosított flag-ek: nem befolyásolja a flag-ek állását.

      Órajel ciklus: 2.

REPZ, REPNZ

         A kiegészítés hatása azonos a LOOP utasítás hatásával.

        Módosított flag-ek: nem befolyásolja a flag-ek állását.

        Órajel ciklus: 2.

CALL  Szubrutin hívása úgy, hogy ip jelenlegi értékét a verembe menti (rövid

       ugrásnál), illetve távoli ugrásnál a cs szegmensregiszter értékét is

       menti.

       Módosított flag-ek: nem befolyásolja a flag-ek állását.

       Órajel ciklus: 16-57.

INT     Software megszakítás eljárás indítása.

      Módosított flag-ek: nem befolyásolja a flag-ek állását.

      Órajel ciklus: 51-52.

INTO  Megszakítási rutin indítása, ha az overflow flag értéke 1.

       Módosított flag-ek: nem befolyásolja a flag-ek állását.

       Órajel ciklus: 53-54.

RET, RETF

        Kiolvassa a veremből a rutin előzőleg elmentett visszatérési címét

       a RET csak IP-t, a RETF a CS:IP-t állítja be,

       ezzel átadják a vezérlést a rutint hívó utasítás utáni sorra.

       Módosított flag-ek: nem befolyásolja a flag-ek állását.

       Órajel ciklus: 20-32.

IRET    Visszatérés megszakítási rutinból.

       Módosított flag-ek: nem befolyásolja a flag-ek állását.

       Órajel ciklus: 32.

NOT    Logikai "nem" művelet, az operandus bitjeit ellenkező értékűre állítja.

      Módosított flag-ek: nem befolyásolja a flag-ek állását.

      Órajel ciklus: 3-24.

NEG    Az operandus kettes komlemensét képzi, azaz invertálja az operandus

      bitjeit, és hozzáad egyet.

      Módosított flag-ek: of, sf, zf, af, cf, pf.

      Órajel ciklus: 3-24.

AND - A logikai "és" művelet eredményei:

      0 & 0 = 0

      0 & 1 = 0

      1 & 0 = 0

      1 & 1 = 1

      Módosított flag-ek: of, sf, zf, cf, pf.

      Órajel ciklus: 3-25.

OR - A logikai "és vagy" művelet eredményei:

     0 | 0 = 0

     0 | 1 = 1

     1 | 0 = 1

     1 | 1 = 1

     Módosított flag-ek: of, sf, zf, cf, pf.

     Órajel ciklus: 3-27.

XOR    A logikai "kizáró vagy" művelet eredményei:

      0 ^ 0 = 0

      0 ^ 1 = 1

      1 ^ 0 = 1

      1 ^ 1 = 0

      Módosított flag-ek: of, sf, zf, cf, pf.

      Órajel ciklus: 3-37.

ROL    Operandus forgatása balra, a kiforduló bit az adat másik szélére és a c

      flag-be íródik.

      Módosított flag-ek: cf, of.

      Órajel ciklus: 2-36.

ROR    Operandus forgatása jobbra, a kiforduló bit az adat másik szélére és a

      c flag-be íródik.

      Módosított flag-ek: cf, of.

      Órajel ciklus: 2-36.

RCL    Az adat forgatása balra a carry biten keresztül. A kicsurdoló bit c-be

      kerül, és az operandus másik szélére innen fordul be.

      Módosított flag-ek: cf, of.

      Órajel ciklus: 2-36.

RCR    Az adat forgatása jobbra a carry biten keresztül. A kicsurdoló bit c-be

      kerül, és az operandus másik szélére innen fordul be.

      Módosított flag-ek: cf, of.

      Órajel ciklus: 2-36.

SHL     Az adat balra tolása úgy, hogy a másik oldalról beforduló bit értéke 0.

      Természetesen a kicsorduló bit itt is a carry-be kerül.

      Módosított flag-ek: cf, zf, of, pf, sf.

      Órajel ciklus: 2-36.

SHR    Az adat jobbra tolása úgy, hogy a másik oldalról beforduló bit értéke

      0. Természetesen a kicsorduló bit itt is a carry-be kerül.

      Módosított flag-ek: cf, zf, of, pf, sf.

      Órajel ciklus: 2-36.

SAL     Az adatot balra tolja, és jobb oldalra a signum bit értéke íródik.

      Módosított flag-ek: cf, zf, of, pf, sf.

      Órajel ciklus: 2-36.

SAR    Az adatot jobbra tolja, és bal oldalra a signum bit értéke íródik.

      Módosított flag-ek: cf, zf, of, pf, sf.

      Órajel ciklus: 2-36.

HLT     Leállítja a processzor működését, innen csak egy reset vagy egy

      hardware interrupt billentheti ki. Az utóbbi esetben a program a

      megszakítás lekezelése után a HLT utasítást követő sortól folytatódik.

      Módosított flag-ek: nem befolyásolja a flag-ek állását.

      Órajel ciklus: 2.

LOCK Egy tetszőleges utasítás előtt használva a művelet végrehajtásának

       idejére lezárja a processzor buszait. Ez főként többproceszoros

       rendszereknél használatos.

       Módosított flag-ek: nem befolyásolja a flag-ek állását.

       Órajel ciklus: 2.

WAIT  A processzort várakozó állásba helyezi, míg a TEST kivezetésen

       ala csony szintet nem kap. Ezt akkor szokták alkalmazni, amikor a

       gépben eltérő sebességű részegységek találhatók, illetve fontos

       szerepe van a matematikai processzorok kezelésénél.

       Módosított flag-ek: nem befolyásolja a flag-ek állását.

       Órajel ciklus: 3.

NOP    Nincs műveletvégzés. Főként ciklusok pontos időzítésére használják.

      Módosított flag-ek: nem befolyásolja a flag-ek állását.

 Órajel ciklus: 3.

 

2. i8086 regiszterek

16 bitesek, azok 8 felső és 8 alsó bitet tartalmaznak.

Általános rendeltetésűek:

AX - Alapértelmezett 16 bites regiszter.
 Felső byte-ja ah, alsó byte-ja al.

További regiszterek  BX, CX, DX.

Szegmensregiszterek:

CS - Kódszegmens

DS - Adatszegmens

ES - Extraszegmens

SS - Veremszegmens.

Indexregiszterek (offsetregiszterek):

SI - Forrásindex

DI - Célindex.

További regiszterek:

BP - Bázismutató.

SP - Veremmutató

IP - Utasításszámláló (private, nem elérhető)

Flag Regiszter

Bitjeinek jelentése van.

A szegmenscímtől az offsetcím 4 bittel van eltolva, így a két regiszter 20 biten ábrázolható.

Pl.

01011100000010010000b (5A090h)

00000000000000001101b (0000Dh)

------------------------------

01010110000010011101b (5A09Dh)

 

3. Péda utasítás használatára (MOV)

mov ax,425

mov ax,52h

mov al,bh

mov ax,címke

mov ax,word ptr [címke]

mov al,byte ptr [címke]

mov ax,[si]

mov al,[si]

mov ax,[si+2]

mov ax,[si+bx+2]

mov ax,es:[si]

mov ax,es:[si+2]

mov ax,offset címke

mov word ptr [címke],ax

mov word ptr [címke],al

mov [si],al

mov [si+bx+2],ax

mov es:[si],ax

mov es:[si+bx+2],ax

 

4. Csatlakozás a Turbo Pascal környezethez

Az alábbi változókat kell alkalmazni a megadott típusokhoz PASCAL-ban az

assembly függvények visszatérési értékeihez:

AL - 8 bites (byte, char, shortint) adatok.

AX - 16 bites (word, integer) adatok.

DX:AX - 32 bites (longint, pointer) adatok.

DX:BX:AX - 48 bites (real) adatok.

@result - String adatok.

ST - Koprocesszor változók.

 

5. A Turbo Assembler formai szabályai

.EXE file:

Kód     Segment

            assume CS:Kód, DS: Adat, SS: Stack

Start:    .

            .

            .

Kód     Ends

Adat    Segment

            .

            .

            .

Stack   Segment

            .

            .

            .

Stack   Ends

            End      Start

.COM file:

Kód     Segment

            assume CS:Kód, DS: Kód

            Org 100h

Start:    .

            .

            .

Kód     Ends

            End      Start

A COM file-nak ell kell férnie egy szegmensben, tehát max. 64 Kbyte méretű

kódot tartalmazhat.

Szűcs Tamás - szucs_t@freestart.hu