Definirea constantelor în limbaj de asamblare
Definirea datelor (variabilelor) în limbaj de asamblare
Declararea și utilizarea segmentelor în limbaj de asamblare
Definirea și utilizarea procedurilor în limbaj de asamblare
Formatul instrucțiunilor în limbaj de asamblare
Structura unui program în limbaj de asamblare
Asamblarea și editarea legăturilorRegistrele microprocesorul 8086
Setul de instrucțiuni al lui 8086
nume EQU <valoare>unde:
nume - numele constantei. Pentru o constantă nu se rezervă spațiu în memorie.Exemple:
<valoare> - reprezintă valoarea ce este atribuită constantei.
PI equ 3.14159 INT_DOS equ 21h BASE_ADDR equ 378h
[nume] <tip> <lista_expresii> [;<comentariu>]sau
[nume] <tip> <factor> DUP(<lista_expresii>) [;<comentariu>]unde:
[ ] - indică faptul că acest câmp poate lipsi;Exemple:
[nume] - numele prin care va fi referită data. Acest nume are asociat un tip și o valoare. Tipul rezultă din tipul datei iar valoarea este adresa la care se va găsi în memorie în timpul execuției programului primul octet rezervat pentru data etichetată cu numele respectiv.
<lista_expresii> - reprezintă lista unor expresii cu ale căror valori se vor inițializa zonele de date rezervate pentru declarația respectivă. Prin ? se specifică faptul că zona respectivă de date nu este inițializată.
<factor> - este un număr care indică de câte ori se repetă lista de expresii care urmează în paranteză.
<tip> - tipul de date:DB - date de tip octet (BYTE) - 8 biți;
DW - date de tip cuvânt sau adresă (WORD) - 16 biți;
DD - date de tip pointer (DWORD) - 32 biți;
DQ - date de tip constantă reală (QWORD) - 8 octeți;
DT - date de tip constantă BCD (TBYTE) - 10 octeți.
x dw 0 y dw ? sir db 'Sir de caractere!' ptr dd 1000h
<nume> SEGMENT [<tip_aliniere>] [<tip>] [<clasa>]unde:
<corpul_segmentului>
<nume> ENDS
<nume> - este numele asociat segmentului. Acestui nume i se asociază o valoare și anume adresa de segment corespunzătoare poziției segmentului în memorie în faza de execuție a programului. Încărcarea unui registru segment cu o adresă de segment se face prin următoarea secvență de instrucțiuni:Având în vedere că într-un program pot să existe mai multe segmente este necesar ca asamblorul să cunoască în fiecare moment care sunt cele patru segmente logice curente pentru a putea să genereze corect codurile instrucțiunilor. De asemenea asamblorul trebuie să știe ce registru de segment se poate utiliza pentru a realiza accesul la datele referite. Această informație este transmisă asamblorului cu ajutorul pseudoinstrucțiunii ASSUME, care are următoarea forma genearală:MOV AX, <nume><tip_aliniere> - poate să fie PARA, BYTE, WORD, PAGE și indică tipul adresei de început a segmentului, adică adresa de început a zonei de memorie rezervată segmentului este divizibilă cu 16, 1, 2, respectiv 256.
MOV DS, AX
<tip> - este o informație pentru editorul de legături. Această informație indică raportul între acest segment și segmente definite în alte module obiect.
ASSUME {<registru_segment> : <segment>}Definirea simplificată a segmentelor: acest tip de declarare a segmentelor este mai simplu de utilizat. Pentru a utiliza acest mod de definire trebuie sa se stabilească întâi care este modelul de memorie pentru care este scris programul respectiv:
.MODEL <tip_model>unde <tip_model> poate fi: TINY, SMALL, MEDIUM, COMPACT, LARGE sau HUGE.
După stabilirea modelului pot apare următoarele pseudoinstrucțiuni:
.STACK [dimensiune] - segmentul de stivă;
.CODE [nume] - segmentul de cod;
.DATA - segmentul de date;
.DATA? - segment de date neinițializate;
.FARDATA [nume] - segment de date la care referirile se fac prin intermediul unor adrese complete (segment și offset);
.FARDATA? [nume]
.CONST - segment de date inițializate, date ale căror valori nu se modifică prin execuția programului.
<nume> PROC [<atribut>]unde:
<corp_procedură>
<nume> ENDP
<nume> - numele prin care se vor face apelurile procedurei. Acest nume are asociată ca valoare adresa primei instrucțiuni din procedură;
<atribut> - FAR sau NEAR.
[<eticheta>:] [<operație> [<operanzi>]] [;<comentariu>]unde:
<eticheta> - un nume care are asociată adresa relativă în cadrul segmentului din care face parte primul octet din instrucțiunea etichetată;
<operație> - mnemonica corespunzătoare instrucțiunii;
<operanzi> - este un câmp a cărui existență și formă depind de tipul instrucțiunii.
;;.286 ; se acceptă instrucțiuni de 286 INT_DOS equ 21h ; definirea unei constante data_seg segment ; segmentul de date hex_digit db '0123456789ABCDEF' data_seg ends bios_seg segment at 0000h ; un alt segment de date care se ; suprapune peste zona de date BIOS bios_seg ends stack_seg segment stack ; segmentul de stivă dw 100h dup (?) top_off label word stack_seg ends code_seg segment 'code' ; segmentul de cod assume cs:code_seg,ds:data_seg,es:data_seg,ss:stack_seg ; definirea procedurilor nume_proc proc near ; input : ; output: ret nume_proc endp ; programul principal start: mov ax,data_seg ; inițializarea segmentului de mov ds,ax ; date mov es,ax ; mov ax,stack_seg ; inițializarea segmentului de mov ss,ax ; stivă mov sp,offset top_off ; ... ; aici se plasează programul end_prog: mov ax,4c00h ; exit to DOS int INT_DOS ; code_seg ends end start
tasm nume_fisier.asm ;
sau
masm nume_fisier.asm
Iar editarea legăturilor:
tlink nume_fisier.obj ;
sau
link nume_fisier.obj
Figura 2.1 Registrele generale ale procesorului 8086
Registrele indicatoare de adresă (SP, BP) - sunt registre care
conțin adrese relative în segmentul stivă curent. Registrul SP are semnificația
de adresă curentă a vârfului stivei, iar registrul BP este utilizat pentru
a permite accesul la informația conținută în stivă.
Registrele index (SI, DI) - sunt utilizate în general pentru adresarea indexată, conținând adrese relative în segmentul de date curent. Segmentul implicit utilizat în adresare poate să fie modificat prin utilizarea în instrucțiuni a unor prefixe speciale. Registrele index sunt utilizate ca registre index implicite în instrucțiunile de transfer sau prelucrare pe șiruri de octeți: SI - adresa relativă curentă în șirul sursă, DI - adresa relativă curentă în șirul destinație.
Figura 2.2 Registrele indicatoare de adresă și index
Registrele segment (CS, DS, ES, SS) - conțin adresa segmentului program (CS), adresa segmentului de date curent (DS), adresa segmentului de date suplimentar (ES) și adresa segmentului de stivă (SS).
Figura 2.3 Registrele segment
Indicatorii de condiții
Sunt utilizați pentru a memora informații referitoare la rezultatul
unor operații aritmetice sau logice (AF, CF, OF, PF, SF, ZF) și pentru
memorarea unor informații de control pentru microprocesor (DF, IF, TF).
MOV <destinație>, <sursă>Instrucțiuni pentru transferul valorilor indicatorilor de condiții
PUSH <sursă>
POP <destinație>
XCHG <destinație>, <sursă> - interschimbă sursa cu destinația;
XLAT - convertește conținutul registrului AL utilizând o tabelă a cărei adresă de început este în BX;
LEA <registru>, <operand> - încarcă în registru adresa relativă a operandului;
LDS <registru>, <adresă> - se încarcă în registrele DS și <registru> adresa aflată în memorie la adresa <adresă>;
LES <registru>, <adresă> - se încarcă în registrele DS și <registru> adresa aflată în memorie la adresa <adresă>;
SAHF - încarcă indicatorii de condiții conform conținutului registrului AH;Instrucțiuni pentru poziționarea indicatorilor de condiție
LAHF - memorează valorile indicatorilor în registrul AH;
PUSHF - salvează pe stivă indicatorii de condiție;
POPF - reface din stivă valorile indicatorilor de condiție.
CLC - pune pe 0 valoarea indicatorului CF;Instrucțiuni aritmetice
STC - pune pe 1 valoarea indicatorului CF;
CMC - comlpementează valoarea indicatorului CF;
CLD - pune pe 0 valoarea indicatorului -DF;
STD - pune pe 1 valoarea indicatorului DF;
CLI - dezactivează sistemul de întreruperi;
STI - activează sistemul de întreruperi.
ADD <d>, <s> - <d> Ź <d> + <s>Instrucțiuni logice
ADC <d>, <s> - <d> Ź <d> + <s> + CF
INC <d> - <d> Ź <d> + 1
AAA - corecție zecimală după adunare BCD despachetat (AL)
DAA - corecție zecimală după adunare BCD împachetat (AL)
SUB <d>, <s> - <d> Ź <d> - <s>
SBB <d>, <s> - <d> Ź <d> - <s> - CF
DEC <d> - <d> Ź <d> - 1
NEG <d> - <d> Ź 0 - <d>
AAS - corecție zecimală după scădere BCD despachetat (AL)
DAS - corecție zecimală după scădere BCD împachetat (AL)
CBW - conversie valoare conținută în AL la cuvânt în AX (extensie de semn)
CWD - conversie valoare conținută în AX la dublu cuvânt în DX, AX (extensie de semn)
MUL <s> - dacă <s> este de tip octet AX Ź AL * <s>
- dacă <s> este de tip cuvânt DX,AX Ź AX * <s>
operanzii sunt tratați ca întregi fără semn
IMUL <s> - dacă <s> este de tip octet AX Ź AL * <s>
- dacă <s> este de tip cuvânt DX,AX Ź AX * <s>
operanzii sunt tratați ca întregi cu semn
AAM - corecție zecimală după o înmulțire BCD despachetat. (MUL)
DIV <s> - dacă <s> este de tip octet AL Ź AX / <s> și AH Ź AX mod <s>
- dacă <s> este de tip cuvânt AX Ź DX,AX / <s> și DX Ź DX,AX mod <s>
operanzii sunt tratați ca întregi fără semn
IDIV <s> - dacă <s> este de tip octet AL Ź AX / <s> și AH Ź AX mod <s>
- dacă <s> este de tip cuvânt AX Ź DX,AX / <s> și DX Ź DX,AX mod <s>
operanzii sunt tratați ca întregi cu semn
AAD - corecție zecimală înainte de o împărțire BCD despachetat. (DIV)
SHL <s>, n - deplasare logică la stângaInstrucțiuni pe șiruri de caractere
SAL <s>, n
SHL <s>, CL
SAL <s>, CL
SHR <s>, n - deplasare logică la dreapta
SHR <s>, CL
SAR <s>, n - deplasare aritmetică la dreapta
SAR <s>, CL
ROL <s>, n - rotire stânga prin carry
ROL <s>, CL
ROR <s>, n - rotire dreapta prin carry
ROR <s>, CL
RCL <s>, n - rotire stânga cu carry
RCL <s>, CL
RCR <s>, n - rotire dreapta cu carry
RCR <s>, CL
NOT <s> - complementează față de 1 pe <s>
AND <d>, <s> - <d> Ź <d> Ù <s>
TEST <d>, <s> - se poziționează indicatorii ca la AND dar nu se modifică <d>
OR <d>, <s> - <d> Ź <d> Ú <s>
XOR <d>, <s> - <d> Ź <d> Ć <s>
CMP <d>, <s> - se poziționează indicatorii ca la SUB dar nu se modifică <d>
MOVSB, MOVSW - transferă un octet, cuvânt între sursă și destinație;
CMPSB, CMPSW - poziționează indicatorii de condiție corespunzător diferenței între sursă și destinație;
SCASB, SCASW - poziționează indicatorii de condiție conform diferenței între AL, AX și destinație;
LODSB, LODSW - încarcă un octet, cuvânt din sursă în AL, AX;
STOSB, STOSW - memorează conținutul AL, AX în destinație;
REP, REPZ, REPE - se repetă operația până când conținutul registrului CX devine zero sau până când indicatorul ZF devine zero.
Instrucțiuni de salt
CALL adresa - apel de procedură;Instrucțiuni de intrare/ ieșire
RET - reîntoarcere din procedură;
JZ, JE - ZF = 1;
JL, JNGE - mai mic (SF ? OF) - comparație valori cu semn;
JLE, JNG - mai mic sau egal (ZF = 1 sau SF ? OF) - comparație valori cu semn;
JB, JNAE, JC - mai mic (CF = 1) - comparație valori fără semn;
JBE, JNA - mai mic sau egal (CF = 1 sau ZF = 1) - comparație valori fără semn;
JP, JPE - PF = 1;
JO - OF = 1;
JNZ, JNE - ZF = 0;
JNL, JGE - mai mare sau egal (SF = OF) - comparație valori cu semn;
JNLE, JG - mai mare (ZF = 0 și SF = OF) - comparație valori cu semn;
JNB, JAE, JNC - mai mare (CF = 0) - comparație valori fără semn;
JNBE, JA - mai mare (CF = ZF = 0) - comparație valori fără semn;
JNP, JPO - PF = 0;
JNO - OF = 0;
JNS - SF = 0;
JCXZ - CX = 0;
IN AL, port
IN AL, DX
OUT port, AL
OUT DX, AL
isch macroApelul unei proceduri:
;Testeaza daca exista caracter disponibil in buffer-ul de tastatura
; input : (none)
; output: zf - 0 caracter disponibil
; - 1 nu e caracter disponibil
...
functia DOS 0bh
...
endmgetch macro
;Citeste un caracter de la tastatura
; input : (none)
; output: al - cod ASCII al caracterului citit
...
functia DOS 01h
...
endmputch macro c
;Afiseaza un caracter pe ecran
; input : c - cod ASCII al caracterului
; output: (none)
...
functia DOS 02h
...
endmdelay macro n
;Introduce o intarziere de n bucle de asteptare
; input : n - numar bucle de asteptare
; output: (none)
...
endmshow_al_bin proc near
;Afiseaza in binar continutul lui AL
; input : al - numar 8 biti
; output: (none)
...
cx Ź 8
repeta
daca bitul 7 din al este 0 atunci
afiseaza 0
altfel
afiseaza 1
al Ź al << 1
cx Ź cx - 1
pana cand cx = 0
...
show_al_bin endpshow_ax_bin proc near
;Afiseaza in binar continutul lui AX
; input : ax - numar 16 biti
; output: (none)
...
apelez show_al_bin pentru AH si apoi pentru AL
...
show_ax_bin endpshow_al_hex proc near
;Afiseaza in hexa continutul lui AL
; input : al - byte
; output: (none)
...
* se definește un tabel care conține șirul 0123456789ABCDEF
bl Ź al
al Ź al >> 4
ah Ź 0
si Ź ax
* afișez caracterul din tabel[si]
al Ź bl
al Ź al & 0fh
si Ź ax
* afișez caracterul din tabel[si]sau:
dl Ź al
dl Ź dl >> 4
dacă dl <= 9 atunci
dl Ź dl + 0
altfel
dl Ź dl + A - 10
* afișez caracterul din registrul dl
dl Ź al
dl Ź dl & 0fh
dacă dl <= 9 atunci
dl Ź dl + 0
altfel
dl Ź dl + A -10
* afișez caracterul din registrul dl
...
show_al_hex endpshow_ax_hex proc near
;Afiseaza in hexa continutul lui AX
; input : ax - word
; output: (none)
...
apelez show_al_hex pentru AH si apoi pentru AL
...
show_ax_hex endpshow_al_bcd proc near
;Afiseaza in BCD continutul lui AL
; input : al - byte
; output: (none)
...
show_al_bcd endpread_al_bin proc near
;Citeste un numar binar pe 8 biti
; input : (none)
; output: al - numarul citit de la tastatura
...
read_al_bin endpread_al_hex proc near
;Citeste un numar hexa pe 8 biti
; input : (none)
; output: al - numarul citit de la tastatura
...
read_al_hex endpcalc_address proc near
;Calculeaza adresa fizica din adresa logica
; input : ax - segment
; dx - offset
; output: ax - primii 4 biti mai semnificativi din adresa fizica
; dx - ultimii 16 biti din adresa fizica
...
adresa fizica = segment * 16 + offset
...
calc_address endp
MOV AL, 0aah ; parametru
CALL show_al_bin
Apelul unui macro:
putch Asau
putch al
Obs.