ASSEMBLER - jazyk symbolických adres

Program je tvořen dvěma druhy klíčových slov:

Direktivy nevytvářejí kód programu, ale řídí činnost překladače.
Instrukce jsou symbolickým zápisem strojových instrukcí procesoru.

  

Syntaxe zápisu instrukce:

návěští instrukce cíl, zdroj ; komentář

 Návěští je symbolické jméno, které označuje offset v daném segmentu.

Návěští:
blízká (NEAR)
vzdálená (FAR)

Blízká návěští představují pouze offsetovou část adresy. Používají se v případě, že se na návěští odkazujeme v rámci segmentu, ve kterém je definováno. Identifikátor blízkého návěští se od instrukce odděluje dvojtečkou.

Vzdálená návěští představují kompletní adresu. Pro definici vzdáleného návěští se používá direktiva LABEL.

Cíl a zdroj jsou operandy instrukce. Operandem může být registr, konstanta, paměťové místo.

Komentář je libovolný text, oddělený od instrukce středníkem.

 

Direktivy nemají přesnou syntaxi zápisu. Pro označení proměnných, návěští, konstant se používají symbolická jména - identifikátory. V assembleru je identifikátor libovolné slovo složené ze znaků: $, % , - , ?, A...Z, a...z, 0-9. Identifikátor nesmí začínat číslicí a nelze pro ně použít rezervovaná slova. Malá a velká písmena se v assembleru nerozeznávají.

 

Paměť je rozdělena na segmenty o velikosti 64 kB. Každý segment je určen segmentovou adresou, která je uložena v některém ze segmentových registrů. Velikost adresy je 16 bitů. Posunutí v segmentu je relativní adresa, vzhledem k jeho počátku, určuje offset. Instrukce programu leží vždy v segmentu označeném registrem CS. Direktiva MODEL umožnuje automatické definování segmentů a jejich vlastností.

Syntaxe:

MODEL paměťový model

Paměťový model blíže určuje jedno ze slov, slovo určuje velikost programu.:

např. MODEL TINY

Všechny segmenty začínají na stejné adrese a velikost programu nesmí překročit 64 kB, tj. jeden segment. Tento model je nutno používat pro programy typu .com.

 

Šablona pro psaní programu typu .com:

IDEAL; zvolení režimu překladače
MODEL tiny; určení velikosti programu
DATASEG; označení datového segmentu
CODESEG;
STARTUPCODE;

<zde bude umístěn kód programu>

EXITCODE; ukončení programu
END

 

DATA

Pro definici dat je syntaxe:

[jméno] direktiva [výraz [, výraz...]]

Jméno je identifikátor, který označuje paměťové místo, je to ukazatel na místo v daném segmentu. Obsahuje adresu a instrukce o velikosti dat. Velikost určuje direktiva:

Direktiva

Velikost

DB

1 byte

DW

2 byte (slovo)

DD

dvojslovo (32 bitů)

DQ

čtyřslovo (64 bitu)

DF

6 bytů (80386 ukazatel FAR)

DP

6 bytů (80386 ukazatel FAR)

DT

10 bytů (pro reálná čísla)

 Výraz: definuje obsah paměťového místa. V případě, že nechceme inicializovat, uvedeme ?. Když ano, uvedeme libovolnou číselnou hodnotu nebo výraz, který se vyhodnotí na číselnou hodnotu. U direktivy DW lze inicializaci provést pomocí řetězce znaků, uzavřeného v úvozovkách nebo apostrofech. Jednotlivé znaky se nahradí ascii hodnotami, kde se pro každý znak vytvoří místo o velikosti 1 B. Výrazy se vyhodnocují při překladu zdrojového textu. Základem výrazu jsou konstanty. Číselné konstanty se mohou zapisovat ve dvojkové, osmičkové, desítkové a šestnástkové soustavě. Číslo musí vždy začínat číslicí. Implicitní soustava je určena direktivou RADIX. Číslo v jiné než implicitní soustavě se napíše tak, že se za něj napíše základ (znak).

RADIX

Syntaxe:

RADIX základ

Základ - 2, 8, 10, 16.

Soustava

Znak

Dvojková

B

Osmieková

O,Q

Desítková

D

Šestnáctková

H

  

Postup při vytváření programu typu .com:

  1. Vytvoříme v některém z editorů soubor .asm.
  2. Přeložíme příkazem TASM jméno souboru - vznikne soubor .obj (relativní program).
  3. Příkazem TLINK jméno souboru / t vytvoříme soubor .com a spustíme.

 

Větvení programu:

Ve vyšších programovacích jazycích se provádí příkazy IF, GOTO, atd. U asembleru se větvení provádí pomocí instrukcí skoku.

Instrukce skoku: podmíněné, nepodmíněné.

Nepodmíněný skok

Syntaxe:

JMP [vzdálenost] cíl

Cíl je návěští, na které chceme skočit, pokud skáčeme uvnitř segmentu, je vzdálenost NEAR, jinak FAR.

Např.
JMP NEAR Reet
. .
. .
Reet: MOV DX, OFFSET BUFFER


Podmíněný skok

Syntaxe:

J podmínka návěští

Provádí se na základě nastavení jednotlivých bitů v registru příznaků. Návěští u podmíněného skoku musí být ve vzdálenosti -128 až +127 bytů od instrukce skoku. Podmínka určuje, kdy se skok provede. Před provedením instrukce podmíněného skoku je nutno nastavovat bity v příznakovém registru. Provádí se instrukcí CMP.

Např.
CMP BL,2
JA ERROR
. .
. .
ERROR:MOV DX,OFFSET MESSAGE
MOV AH,09H
INT21H

 

CMP

Syntaxe:

CMP cíl, zdroj

Instrukce odečte zdroj od cíle a podle toho nastaví bity v příznakovém registru, obsah cíle ani zdroje se nemění.

Cykly

V assembleru se realizují pomocí instrukcí skoku. Pomocí JNZ je realizován cyklus DO - WHILE.

Příklad:

CODESEG
. .
návěští:
     <tělo cyklu>
     JNZ návěští

 

Cyklus FOR (for i =1 to 10):

MOV CX,1
LOOP1,<tělo cyklu>
   INC CX
   CMP CX,10
   JNZ LOOP1

Jeden z registrů se použije jako čítač, který při každém průchodu dekrementuje nebo inkrementuje a před podmíněným skokem porovnáváme s nějakou hodnotou.

  

Instrukční soubor 80386

NOP

Syntaxe:
NOP

Prázdná instrukce, neprovádí nic, změní jen obsah čítače programu.

 

INC

Syntaxe:
INC reg

Instrukce přičte ke svému operandu jedničku a výsledek do něj opět uloží.

 

DEC

Syntaxe:
DEC reg

Instrukce odečte od svého operandu jedničku a výsledek do něj opět uloží.

 

DIV

Syntaxe:
DIV oper

Instrukce dělí celá čísla bez znaménka, má jen jeden operand, výsledkem dělení je dvojice čísel: celočíselný podíl, celočíselný zbytek.

Velikost operandu

Dělenec

Dělitel

Podíl

Zbytek

8 bitů

AX

operand

AL

AH

16 bitů

DX:AX

operand

AX

DX

32 bitů

EDX:EAX

operand

EAX

EDX

Např. při bytovém dělení je dělenec v registru AX, podíl v AL a zbytek v AH. Znamená to, že umístění dělence, podílů a zbytků závisí na velikosti operandů.

 

 

Zásobník

LIFO (Last In First Out)

pix6_1.gif (1641 bytes)

Ukládají se přechodně: obsahy registrů, návratové adresy.

Údaj naposled vložený do zásobníku zaujímá vždy nejnižší adresu. Zásobník je vymezená souvislá část paměti RAM. Nejnižší adresa je vrchol zásobníku. Adresa vrcholu zásobníku je obsažena v ukazateli SP. Údaje jsou do zásobníku vkládány v pořadí. Na vrcholu je vždy údaj, který byl vložen jako poslední. Zásobník se plní směrem k nižším adresám a vyprazdňuje směrem k vyšším adresám. Zvyšování nebo snižování obsahu provádí mikroprocesor při instrukcích, pracujících se zásobníkem.

 Vyjmutí ze zásobníku:

POP

Syntaxe:
POP oper

Instrukce vyjme slovo nebo dvojslovo ze zásobníku a uloží ho do operandu. Pak se k obsahu registru SP přičtou 2, pokud je vybíráno slovo nebo 4, pokud je vybíráno dvojslovo. Při vybírání ze zásobníku se adresa SP zvyšuje.

Příklad: POP AX

 

POP A

Instrukce vybírá 8 základních registrů ze zásobníku:

DI, SI, BP, SP, BX, DX, CX, AX. Lze ji nahradit osmi instrukcemi POP.

 

 

Ukládání na zásobník:

PUSH

Syntaxe:
PUSH oper

Instrukce uloží obsah registru, paměti nebo přímo hodnotu na zásobník. Ukazatel vrcholu zásobníku ukazuje na naposledy uloženou položku. Nejprve se odečtou od obsahu registru SP 2 (ukládáme-li slovo) nebo 4 (ukládáme-li dvojslovo), takže registr SP ukazuje na volné místo. Pak se zapíše obsah registru, paměti nebo konstanty. Při ukládání do zásobníku se adresa registru SP snižuje.

 

PUSH A

Instrukce ukládá 8 základních registrů do zásobníku:

AX, CX, DX, BX, SP, BP, SI, DI. Po provedení této instrukce je obsah registru AX na nejvyšší adrese v zásobníku a DI je na nejnižší adrese v zásobníku.

 

ADD

Syntaxe:
ADD oper1, oper2

Instrukce provádí součet dvou operandů.  oper1 = oper1 + oper2

 Např:

MOV AX,2
MOV BX,3
ADD AX,BX ; AX [5]

 

MOV

Syntaxe:
MOV oper1, oper2

Instrukce naplní operand oper1 operandem oper2, přitom oper2 zůstane beze změny.

 Např:

MOV BX,4
MOV BX,AX

 

MUL

Syntaxe:
MUL oper1

Instrukce provádí násobení celých čísel bez znaménka.

Velikost

1. činitel

2. činitel

Součin

8,00

AL

operand

AX

16,00

AX

operand

DX:AX

32,00

EAX

operand

EDX:EAX

 1. oper1 je 1B

Oper1 se vynásobí registrem AL a výsledek se uloží do AX. Když je výsledek větší než 1B, nastaví se příznaky OF a CF, jinak se oba příznaky nulují.

2. oper1 je slovo

Oper1 se vynásobí registrem AX a výsledek se uloží do DX a AX tak, že nižší část výsledku je v registru AX a vyšší v DX. Je-li výsledek větší, nastaví se OF a CF.

3. oper1 je dvojslovo

Oper1 se vynásobí registrem EAX a výsledek se uloží do EDX a EAX tak, že nižší část výsledku je v registru EAX a vyšší v EDX.

 

SUB

Syntaxe:
SUB oper1, oper2

Instrukce provádí odčítání celých čísel.  oper1 = oper1 - oper2

Logické instrukce

AND

Syntaxe:
AND oper1, oper2

Instrukce provádí logický součin operandů podle vzorce. oper1 = oper1 AND oper2

Instrukce AND

1. bit

2. bit

Výsledný bit

0

0

0

0

1

0

1

0

0

1

1

1

 

NOT

Syntaxe:
NOT oper1

Instrukce provádí negaci všech bitů operandu oper1 tak, že bit s hodnotou 1 bude nulový a naopak.

Příklad: NOT BX

 

 OR

Syntaxe:
OR oper1, oper2

Instrukce provádí logický součet operandů podle vzorce. oper1 = oper1 OR oper2

Instrukce OR

1. bit

2. bit

Výsledný bit

0

0

0

0

1

1

1

0

1

1

1

1

 

 XOR

Syntaxe:
XOR oper1, oper2

Instrukce provádí neekvivalenci operandů podle vzorce. oper1 = oper1 XOR oper2

Instrukce XOR

1. bit

2. bit

Výsledný bit

0

0

0

0

1

1

1

0

1

1

1

0

  

Procedury

Procedura je libovolná část kódu programu, která je ukončena instrukcí RET. Návěští označuje začátek procedury.

CALL

Syntaxe:
CALL oper1

Instrukce provede vstup do podprogramu tak, že nejprve se na zásobník uloží návratová adresa a pak se provede skok do podprogramu. Návratová adresa: segment - vyšší část adresy, offset - nižší část adresy. V závislosti na tom, zda podprogram ve stejném segmentu jako hlavní program je i: NEAR - na zásobník se uloží jen offsetová část adresy.

Podle typu volání je i instrukce RET: RETN, RETF.

Instrukce RET způsobí návrat z procedury.

RET

Syntaxe:
RET oper1

Oper1 udává, kolik bytů se odstraní ze zásobníku po vyjmutí návratové adresy.

CODESEG
..................
CALL NEAR PROC1
....................
PROC1:

;zde bude kód procedury

RETN

 

Schéma procedury v ASM

Volání direktivou PROC

Schéma volání

. .
. .
CODESEG
. .
. .
CALL PROC2
. .
PROC PROC2

;zde budou instrukce procedury

RET

 

Při použití direktivy MODEL nemusíme specifikovat, zda je procedura blízká nebo vzdálená. Překladač vybere správný typ podle zadaného modelu. Předávání parametrů pomocí zásobníku:

na zásobník se umístí předávané parametry instrukcí PUSH.

Např:

MOV AX,PARAM1
PUSH AX
MOV AX PARAM2
PUSH AX
CALL PROC2
 

Adresa

Obsah

SP

Návratová adresa

SP + 2

Parametr 2

SP + 4

Parametr 1

Po návratu z procedury je nutno hodnoty ze zásobníku vyjmout. Provádíme instrukci POP.