MASM
(Macro Assembler)
Conf.
Dr. Carmen Timofte
MS-DOS poate să încarce și să execute 2 tipuri de programe:
- .EXE conțin un antet cu informații folosite de încărcătorul de sistem pentru a executa ajustările la referințele de segment (relocări în momentul încărcării); au o dimensiune mai mare de 64 KB; au o structură multisegment (stivă, date, cod)
- .COM conțin imaginea binară a datelor și codului unui program; au o dimensiune mai mică de 64 KB; nu se fac relocări ale adreselor de segment; au un singur segment, care include date și cod; se încarcă mai repede în memorie.
Fișierele .EXE au structura:
- segment de stivă memorează datele care trebuie salvate și reapelate apoi de program; poate apărea în orice ordine față de celelalte segmente;
- segment de date conține variabilele referite de segmentul de cod; trebuie să fie plasat înaintea lui;
- segment de cod conține instrucțiunile executabile, începând cu o etichetă care identifică punctul de intrare în program
Terminarea execuției unui program .EXE se
realizează cu INT 21H, iar registrul AX încărcat cu funcția 4C00H.
Medii de dezvoltare: MASM,
TASM (Turbo Assembler), TASM pe 64b . Emulator- DosBox Portable. Se
lucrează cu oricare dintre ele!
· Emu8086
Exemplificare pentru MASM:
- Editarea programelor se realizează cu orice editor ASCII. Programul sursă se va salva cu extensia specifică limbajului utilizat;
exp: numefis.asm;
- Translatarea programului sursă în limbaj binar se detectează eventualele erori de sintaxă, semantică; translatoarele sunt de 2 feluri: asambloare (specifice fiecărui sistem de calcul) și compilatoare. Dacă în urma translatării apar erori, se reia de etapa de editare, iar dacă nu sunt erori, se obține un program obiect (numefis.obiect)
Se realizează cu programul MASM.EXE, astfel:
MASM
<enter>
Numele_programului.asm= numefis.asm
Numele_programului_obiect.obiect= <enter> și preia numele de sus, sau se
introduce un nume nou
Numele_programului_listing.lst= <enter> sau alt nume ; acest fișier este
destinat listării
- Editarea de legături (link editare) permite efectuarea de legături între mai multe module obiect. Are ca rezultat un fișier cu extensia .exe. Se realizează cu programul LINK.EXE, asftel:
LINK
<enter>
Numele_fișierului_obiect=
numefis.obiect
Numele_fișierului_executabil=<enter>
sau se introduce un nume nou.
- Încărcarea în memoria internă și execuția efectivă se urmărește vizualizarea codului executabil al programului, rulat cu TRACE (pas cu pas)(ALT + T). Se realizează cu programul CV.EXE (Code View), asftel:
cv
numefis.exe
Pentru a vizualiza zona de memorie în care se află rezultatele se folosește comanda din SO Windows 9x/2000/NT, numită DEBUG:
debug numefis.exe
-? (permite aflarea tuturor subcomenzilor din
mediul debug)
-
t (rulare Trace)
- d DS:0000 (Dump de memorie pentru segmentul de date DS; adresa lui DS se vede la comanda t; DATELE IN MEMORIE SUNT REPREZENTATE INVERS DECAT IN REGISTRII MICROPROCESORULUI !!!)
-
q (quit)
Dispune de 13 registrii, astfel:
- 8 reg. generali, astfel:
- 4 reg. de date:
AX acumulator (pentru instrucțiuni aritmetice)
BX de bază
CX contor
DX de date, pentru operații de *, /;
Exp. de registru pe16 biți
AX: 15 AH 8 7 AL 0 AX are 2B = 1 word (cuvânt)
AH= A HIGHT
AL= A LOW
- 4 reg. de pointer și indecși:
SP Stack Pointer memorează adresa curentă a vârfului stivei
BP Base Pointer- păstrează adresa din interiorul stivei, folosit la citirea unui cuvânt din stivă, fără a-l extrage
SI Source Index păstrează valoarea indexului necesară adresării unui șir de caractere;
DI Destination Index idem;
- 4 reg. de segment
CS Code Segment destinat adresării segm. de instrucțiuni curente
DS Data Segment - destinat adresării segm. de date
ES Extended Segment - destinat adresării segm. extins de date
SS Stack Segment - destinat adresării stivei curente a programului
- 1 reg. pentru memorarea adresei următoarei instrucțiuni din segmentul curent IP (Instruction Pointer)
Indicatorii de condiție:
- indicatori de stare de tip Read-Only; sunt poziționați de instrucțiunile aritmetico-logice și nu pot fi decât citiți de programatori:
AF (Auxilliary Flag) are valoarea 1 dacă apare transport între rangurile 3 și 4;
CF (Carry Flag) are valoarea 1 dacă apare transport pe poziția cea mai semnificativă;
OF (Overflow Flag) are valoarea 1 dacă apare depășire;
SF (Signe Flag) are valoarea 1 dacă bitul de pe poziția cea mai semnificativă este 1;
PF (Parity Flag) are valoarea 1 dacă numărul biților din byte-ul cel mai puțin semnificativ este par;
ZF (Zero Flag) are valoarea 1 dacă rezultatul operației anterioare a fost 0.
- indicatori de control de tip Read-Write; sunt fixați de utilizator:
DF (Direction Flag) are valoarea 1 dacă șirul de caractere este parcurs crescător;
IF (Interrupt Flag) are valoarea 1 dacă se consideră întreruperile externe;
TF (Trace Flag) are valoarea 1 dacă programul se execută pas cu pas.
Reprezintă maniera în care datele sunt memorare și accesate din memoria interna a microprocesorului.
Există 8 moduri de adresare:
1- adresare imediată operandul se găsește într-un un cuvânt (word) imediat după codul
instrucțiunii
ex: MOV AX, 15
muta valoarea 15 in registrul acumulator AX;
2- adresare utilizând registre
generale valoarea operandului se găsește într-un
registru general
ex: MOV AX, BX
mută conținutul registrului BX
în registrul AX;
3- adresare directă valoarea operandului se găsește la adresa specificată în instrucțiune
ex: MOV AX, LUCRU
muta conținutul variabilei
LUCRU în AX;
4- adresare indirectă valoarea operandului se găsește în locațîa definită la adresa adresei aflată în instrucțiune
ex: MOV AX, [BX]
în BX se află o adresă; la adresa specificată în BX se găsește o altă adresă; la a II-a adresă se găsește operandul care va fi mutat în AX;
5- adresare cu registre de bază -
ex: MOV AX, [BX] val (pt. <DS:BX>)
MOV AX, [BP] val (pt. <SS:BP>)
se utilizează pentru șiruri de
date;
adresa relativă= valoarea din
registrul de bază + val;
6- adresare cu registre de index - adresa relativă= valoarea din registrul de index + val;
ex: MOV AX, [SI] val (pt. <DS:SI>)
MOV AX, [DI] val (pt. <DS:DI>)
se utilizează pentru tratare
șiruri de date;
7- adresare cu registre de bază și registre de index-
ex: MOV AX, [BX] [SI]
adresa relativă= valoarea din
registrul de bază + valoarea din registrul de index;
8- adresare cu registre de bază, registre de index și offset -
ex: MOV AX, [BX] [SI]val
MOV AX, [BP] [SI]val
MOV AX, [BX] [SI]val
MOV AX, [BP][DI]val
adresa relativă= valoarea din
registrul de bază + valoarea din registrul de index +val;
§ Un program în MASM se compune din mai multe segmente:
- segment de stivă;
- segment de date;
- segment de cod.
§ Un program poate să înceapă cu directiva NAME, care atribuie un nume programului.
§ Fiecare segment începe cu directiva SEGMENT și se termină cu directiva ENDS.
Exp:
nume SEGMENT
nume ENDS
§ Programul se termină cu directiva END.
§ O directivă obligatorie este directiva
care definește registrii de segment (CS, DS, ES, SS) folosiți de fiecare segment în parte.
§ Directiva SEGMENT marchează începutul segmentului. Sintaxă:
nume SEGMENT tip_aliniere, tip_combinare, clasă
unde:
tip_aliniere reprezintă multiplul adresei de segment; poate lua valorile:
.BYTE - multiplu de 1;
.WORD - multiplu de 2;
.PARA - multiplu de 16;
.PAGE - multiplu de 256.
tip_combinare reprezintă adresa cerută de link-editor pt. a încarca în memorie diferite module; poate lua valorile:
PUBLIC 2 segm. cu același nume din 2 module diferite vor fi încărcate în memorie prin acoperire parțială;
COMMON- idem, dar se vor suprapune total;
AT <expr.>- idem, dar se vor încărca la adresa specificată în expresie;
STACK idem, dar se vor încărca în segmentul de stivă;
MEMORY - idem, dar se vor încărca în orice locație liberă din memorie;
blank se vor crea segmente separate de tip PRIVATE.
clasă reprezintă un șir de caractere între ; segmentele care au această clasă sunt încărcate in memorie în locații contigue, apropiate.
§ VARIABILELE sunt elemente de date definite prin:
- tip poate fi:
DB (Define Byte) date de lungine 1B;
DW date de lungime 2 B (1 Word);
DD - ------,,------------ 4 B (2 W);
DQ- -------;;----------- 8 B (4 W);
DT - -------;;---------- 10 B.
- segement poate fi: CS, DS, SS, ES
- offset valoare întreagă fără semn care reprezintă distanța față de baza segmentului;
- de tip șir succesiune de caractere ASCII cuprinse între sau ;
- de tip numeric pot fi :
-binare (B)
-octalw (Q)
-zecimale (D)
-hexazecimale (H)
-virgulă mobilă (L, E)
1. Aritmetici :
- unari: - (negare)
-
binari: *, /, MOD, +, -, SHL
(shift left), SHR (shift right)
Exp.: MOV AX, 100H/7 (operanzii trebuie să fie valori absolute)
MOV AX, 1010000B SHR 3 (mută în AX 1010B)
2. Relaționali : LE (left equal), LT (left than), EQ (equal), GT (great than), GE
(great equal), NE (not equal)
3. Logici : .AND., .OR., .XOR., .NOT.
4. Analitici : SEG, OFFSET, TYPE, LENGTH,
SIZE, .TYPE
- returnează informații despre expresiile
specificate; expresiile pot fi variabile, adrese, etichete, constante;
SEG -
returnează conținutul registrului de segment atașat variabilei sau etichetei
specificate
Sintaxă: SEG var/etichetă
Exp: MOV AX, SEG var1 - mută în reg. AX, conținutul registrului de
segment din care face parte var1
OFFSET returnează deplasarea variabilei sau
etichetei specificate față de începutul segmentul în care a fost definit
Sintaxă: OFFSET var/etichetă
TYPE -
Sintaxă: TYPE var returnează lungimea în
bytes a tipului de dată corespunzător variabilei specificate; dacă este de tip
byte, returnează 1, Word, 2 etc.
Exp: var1 DW 100
..................
MOV AX, TYPE var1 - mută în AX valoarea 2
Sintaxă: TYPE etichetă returnează distanța
asociată etichetei specificate; poate lua valorile NEAR sau FAR.
LENGHT var returnează nr. de apariții al tipului
de variabilă; se utilizează pentru variabile de tip vector, când returnează
numărul de elemente al vectorului.
Exp: var1 DW 100
..................
MOV AX, LENGHT var1
- mută în AX valoarea 1
SIZE var returnează lungimea în bytes a
variabilei specificate; SIZE=TYPE*LENGHT;
Exp: var1 DW 100
..................
MOV AX, SIZE var1 - mută în AX valoarea 2
5. Sintetici : PTR, THIS, SHORT, HIGH, LOW, OVERWRITE
Permit modificarea atributelor unei
expresii, care poate fi: variabilă, etichetă, adresă, constantă.
PTR modifică temporar atributul corespunzător
expresiei specificate;
Sintaxă:
atribut PTR expresie
Atributele pot fi:
-
de distanță: NEAR, FAR;
-
în funcție de tipul expresiilor: BYTE, WORD, DWORD, QWORD, TBYTE, STRUC.
Exp: var1 DW 100
..................
MOV AH, var1 - incorect
MOV
AH, BYTE PTR var1 - var1 va fi
considerată ca o zonă de 1B, în cadrul
acestei instrucțiuni; are caracter temporar;
THIS definește o adresă de memorie, fără a o
rezerva;
Sintaxă: THIS var/etichetă
SHORT etichetă efectuează un salt prin
intermediul instrucțiunii JUMP în interiorul a 127B
Exp: JMP SHORT et1
HIGH var / LOW var extrag dintr-un cuvânt,
byte-ul cel mai semnificativ, respectiv cel mai puțin semnificativ
Exp: var1 DW 100
..................
MOV AH, HIGH var1 - mută în AH p.c.m.s. din var1
MOV AL, LOW var1 - mută în AL p.c.m.p.s. din var1
6. Tratare înregistrări: SHIFT COUNT, WIDTH, MASK
1. Directive condiționale
2. Directive pentru erorile
condiționale
3. Directive pentru declararea și
alocarea datelor: ASSUME, GROUP, INCLUDE, EQU, ORG, =,
EVEN, DB, DW, DD, DQ, DT, DUP, RADIX, RECORD, STRUC, PROC, LABEL
4. Directive pentru controlul
listării și a fișierelor de listare: PAGE, .TITLE,
.LIST, .CREF, XCREF
5. Directive pentru declararea
macroinstrucțiunilor sau macrodefiniților
6. Directive pentru controlul
modului de lucru
7. Directive pentru încarcarea
segmentului
EQU asociază simbolul cu expresia specificată
Sintaxă: simbol EQU expresie
Exp: A EQU 50
- în loc de constanta 50 se folosește simbolul A
ORG expr șterge conținutul registrului
locației curente IP și îl înlocuiește cu valoarea rezultată din evaluarea expresiei;
dacă apare $, se calculează de la valoarea curentă a IP;
Exp: ORG 7
- IP ia valoarea 7
ORG 7+2 IP ia valoarea 9
ORG $+2 - IP=IP+2
EVEN nu are parametrii și are ca efect forțarea unei adrese pare pentru
instrucțiunea următoare.
.RADIX expresie modifică asumția implicită a
calculatorului; expresia poate fi 2, 8, 16
Exp: MOV AX, 55
- mută 55 în baza 10 în AX
.RADIX 8 - modifică baza
implică de lucru din 10 în 8
MOV AX, 55 muta 55 (baza 8) în AX
Directive
pentru alocarea și inițializarea datelor
nume_var {DB/ DW/ DD/ DQ/ DT}
[expresie]
alocă o zonă de memorie cu lungimea de 1B
sau 2B ,.... sau 10B și eventual inițializarea ei cu o valoarea rezultată din
evaluarea expresiei.
- dacă apar mai multe constante separate
prin virgulă, se rezervă o zonă de memorie multiplă;
Exp: var1 DB 5,7,3 se declară 3 zone de
memorie, fiecare de 1 B, inițializate cu valorile 5, 7, 3.
- dacă apare semnul ?, zona de memorie va fi
neinițializată, ci doar rezervată;
Exp: var1 DW ?
-valorile de sus pot fi mixate
Exp: var1 DW 3,2,?, 5,7
DUP semnifică declararea unui vector de date,
cu numărul de elemente specificat,inițializat sau nu;
Sintaxă:
nume_var {DB/ DW/ DD/ DQ/ DT}
numar DUP (expresie)
Exp: vect DW 100 DUP (5,7) - alocă o zonă de memorie unui vector de 100
de elemente, fiecare de 1W, inițializat asftel: primul element 5,al doilea 7,
al treilea 5 etc.
Câmpul expresie poate fi și un șir de caractere ASCII, cuprinse între apostrofuri.
Exp: sir DB LIMBAJE se rezervă 7B,
inițializați cu caracterele L, I, ..., E.
§ INSTRUCȚIUNI PT. EXEC.
OPERAȚII
adună sursa (registru, zonă de memorie, constantă) la destinația (AX, zonă de memorie, registru), punând rezultatul în destinație.
SUB destin, sursă
scade sursa din destinație, punând rezultatul în destinație
DIV sursă
Execută împărțirea dintre:
|
Deîmpărțit |
: |
Împărțitor |
= |
Cât |
Rest |
Pe byte |
AL |
: |
Sursă |
= |
AL |
AH |
Pe word |
AX |
: |
Sursa |
= |
AX |
DX |
MUL destin
Execută înmulțirea dintre:
|
|
|
|
|
p.c.m.s. |
p.c.m.p.s. |
Pe byte |
AH |
* |
Sursă |
= |
AH |
AL |
Pe word |
AX |
* |
Sursa |
= |
DX |
AX |
CMP destin, sursă
Realizează operația de scădere (comparare) între sursă și destinație, punând indicatorii de condiție în funcție de rezultat; sursa și destinația rămân nemodificate.
CMPS șir_destin, șir_sursă - compară șirurile; se utilizează regiștrii SI, DI.
§ INSTRUCȚIUNI DE SALT
JE etichetă - (Jump =) salt la etichetă dacă cei 2 operanzi implicați în operația de comparare anterioară sunt egali)
JL etichetă - Jump Less
JG etichetă - Jump Great
JMP etichetă
INC destinație
DEC destinație
§ INSTRUCȚIUNI PT. APEL INTRERUPERI (interne software/ externe hardware)
IRET - reconstituie contextul inițial al programului
INTO - în caz de depășire (Interrupt Overflow)
§ INSTRUCȚIUNI PT. INCARCARE DE ADRESE
LEA dest, sursă - Load Effective Addresse
LDS -----,,------ - Load Data Segment
LES -----,,----- - Load Extended Segment
PUSH sursă - depune în stivă (SP=SP+2)
POP destin - extrage din stivă (SP=SP 2)
MOV destin, sursă - mută sursa în destinație
§ INSTRUCȚIUNI PT. MUTARE DE ȘIRURI
MOVS dest, sursa - pt. adresarea sirurilor sursă/destinație se folosesc reg. SI/ DI
MOVSB ------;;------ - se mută 1 B
LODS - idem MOVS
LODSB - idem MOVSB
LODSW - idem MOVSW
§ INSTRUCȚIUNI DE CICLARE
LOOP etichetă - decrementează cu 1 registrul CX; dacă
valoarea lui CX<>0, atunci se execută salt la eticheta specificată
Să se calculeze expresia E= a+b-c, unde a,b,c sunt numere generate în memorie la nivel de byte.
Vom folosi SI pe a fi contor de adrese, offset pentru deplasare în cadrul șirului de date.
stiva DB 128 DUP (?)
segm_stiva ENDS
segm_date SEGMENT
sir_date DB 7,23,13, ?
segm_date ENDS
segm_cod SEGMENT
ASSUME CS:segm_cod, DS:segm_date,
SS:segm_stiva
et: MOV
AX, segm_date
MOV DS, AX
MOV SI, offset sir_date
MOV AL, [SI]
ADD AL, [SI+1]
SUB AL, [SI+2]
MOV [SI+3], AL
MOV AX, 4C00H
INT 21H
segm_cod ENDS
END et
- G. Muscă, Programarea în limbaj de asamblare, Ed. Teora, 1997 (1999);
- Floarea Năstase, Sisteme de calcul și operare elemente ale limbajului de asamblare, ASE, București, 1997;
- Dan Somnea, Teodor Vlăduț, Programarea în ASSEMBLER, Ed. Tehnică, 1992;
- Irina Athanasiu, Alexandru Pănoiu, Microprocesoarele 8086, 286, 386- Programarea în limbaj de asamblare, Ed. Teora, 1992;
- Vlad Căprăriu, Sistemul de operare DOS Funcții sistem, Microinformatica, Cluj-Napoca, 1991.