MASM (Macro Assembler)

Conf. Dr. Carmen Timofte

 

1.      Structura fişierelor .exe şi .com

2.      Etapele de dezvoltare a programelor in MASM

3.      Arhitectura microprocesorului 8086 – registrii microprocesorului

4.      Modurile de adresare ale datelor   

5.      Elemente de bază ale limbajului de asamblare

6.      Exemple de programe în MASM

7.      Bibliografie

 

1.      Structura fişierelor .exe şi .com

 

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.

 

2.      Etapele de dezvoltare a programelor în MASM

 

Medii de dezvoltare: MASM, TASM (Turbo Assembler) (care ruleaza sub DOS Box Potable). Alte variante: TASM pe 64b , GUI TASM.

 

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

            şi se deschide o fereastră care arată instrucţiunile şi adresele lor, conţinutul regiştrilor microprocesorului şi flag-urile (F2).

 

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)

 

1.      Arhitectura microprocesorului 8086 – registrii microprocesorului

 

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.

 

2.      Modurile de adresare ale datelor  

 

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;

 

3.      Elemente de bază ale limbajului de asamblare

 

§         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

ASSUME reg_segm: nume_segm

 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;

 

§         CONSTANTELE – sunt de 2 tipuri:

-         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)

 

§         OPERATORI

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

 

 

§         DIRECTIVE

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

ADD   destin, sursă

            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)

INT      tip_întrerupere              - un nr. întreg între [0, 255]

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

MOVSW         ------;;------    - se mută 1 W

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ă

 

4.      Exemple de programe în MASM

 

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.

 

segm_stiva        SEGMENT

            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

 

Exemple de programe

 

5.      Bibliografie

 

-         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.