transferul parametrilor pentru proceduri

42
Transferul parametrilor pentru proceduri Programele scrise în LNI folosesc anumite convenţii pentru transmiterea parametrilor către subprograme. Compilatorul translatează o instrucţiune de apel a unui subprogram astfel: depune în stivă (push) argumentele subprogramului şi apelează apoi subprogramul, cu o instrucţiune de apel (call). În funcţie de compilator argumentele sunt puse în stivă într-o anumită ordine. În cazul în care se leagă o procedură scrisă în LA cu un program scris într-un LNI trebuie cunoscut modul de transmitere a parametrilor şi convenţiile stabilite de limbajul respectiv pentru apel de subprogram (nume externe, valori returnate). Parametrii pot fi transmişi prin valoare sau prin referinţă. În Pascal şi în C se cunosc ambele mecanisme de transmitere a parametrilor. Limbajele de nivel înalt folosesc pentru returnarea de valori către programul apelant, următoarele registre: (AL) - pentru valori de 1 octet; (AX) - pt. valori de 2 octeţi, sau adresă de tip NEAR; (EAX)- valori de 4 octeţi sau adresă de tip NEAR la 386/486; (DX,AX)- valori de 4 octeţi sau pointer FAR, pt. 286; (EDX,EAX)- valori de 8 octeţi sau pointer FAR, pt. 386/486;

Upload: odelia

Post on 29-Jan-2016

54 views

Category:

Documents


0 download

DESCRIPTION

Transferul parametrilor pentru proceduri - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Transferul parametrilor pentru proceduri

• Transferul parametrilor pentru proceduriProgramele scrise în LNI folosesc anumite convenţii pentru

transmiterea parametrilor către subprograme. Compilatorul translatează o instrucţiune de apel a unui subprogram astfel: depune în stivă (push) argumentele subprogramului şi apelează apoi subprogramul, cu o instrucţiune de apel (call). În funcţie de compilator argumentele sunt puse în stivă într-o anumită ordine.

În cazul în care se leagă o procedură scrisă în LA cu un program scris într-un LNI trebuie cunoscut modul de transmitere a parametrilor şi convenţiile stabilite de limbajul respectiv pentru apel de subprogram (nume externe, valori returnate).

Parametrii pot fi transmişi prin valoare sau prin referinţă.În Pascal şi în C se cunosc ambele mecanisme de transmitere a

parametrilor. Limbajele de nivel înalt folosesc pentru returnarea de valori către programul apelant, următoarele registre:(AL) - pentru valori de 1 octet;(AX) - pt. valori de 2 octeţi, sau adresă de tip NEAR;(EAX)- valori de 4 octeţi sau adresă de tip NEAR la 386/486;(DX,AX)- valori de 4 octeţi sau pointer FAR, pt. 286;(EDX,EAX)- valori de 8 octeţi sau pointer FAR, pt. 386/486;

Page 2: Transferul parametrilor pentru proceduri

Pentru valori mai mari de 4 octeţi, limbajul C consideră valoarea întoarsă în zona de memorie alocată pentru segmentul de date, şi returnează în (DX:AX) pointerul către acea zonă.

Limbajul PASCAL rezervă o zonă de date în stivă: zona rezervată în stivă şi offsetul către aceasta se realizează de către programul apelant; procedura returnează în (DX:AX) pointerul la zonă.

Descărcarea stivei se face în programul apelant, procedura terminându-se cu RET, sau pentru descărcarea unor argumente se poate termina cu RET număr_argumente*dimensiune.

Deci, în principiu, programul apelant realizează operaţiile:- depune argumentele în stivă;- apelează procedura;- descarcă stiva;

Variabilele locale într-o procedură se folosesc pentru a economisi spaţiu de memorie (cu menţiunea că valorile lor nu se transmit în afara procedurii). Spaţiul de memorie necesar pentru variabilele locale se rezervă în stivă şi el este eliberat la terminarea execuţiei procedurii.

Page 3: Transferul parametrilor pentru proceduri

Alocarea de spaţiu pentru variabilele locale se realizează cu o secvenţă de forma:

push bpmov bp,spsub sp,n ; n = număr de octeţi alocaţi;

Pentru accesarea variabilelor locale se vor utiliza adresări de forma: [BP - 2], [BP - 6], etc.

iar pentru argumente, de forma: [ BP + 2 ], [ BP + 4 ], etc.argument equ <[bp+6]>var_loc equ <[bp-2]>p1 proc far

push bp ; salvare valoare BPmov bp,sp ; iniţializare cu vârful curent al stiveisub sp,2 ; rezervare spaţiu pt. var_loc, 2 octeţi mov var_loc,0 ; iniţializare varaibilă locală. . . . . . . . . . mov ax,argument ; se ia argumentul transmis prin stivăadd var_loc,ax ; utilizarea variabilei locale. . . . . . . . . .

Page 4: Transferul parametrilor pentru proceduri

mov sp,bp ; eliberarea spaţiului rezervat var_locpop bp ; refacerea valorii lui BPret ; sau ret 2, dacă se descarcă stiva în procedură

p1 endp

Dacă descărcarea stivei nu se face în procedură, atunci în programul apelant trebuie descărcată stiva cu:

add sp, 2

Page 5: Transferul parametrilor pentru proceduri

• Convenţiile utilizate de limbajele de nivel înaltpentru transferul parametrilor pentru proceduri

Să considerăm o procedură, definită în PASCAL:procedure modul (a : integer; var b : real);begin. . . . . . end;

iar apelul de forma:modul (x, y);

Pentru această procedură se va genera secvenţa:push bpmov bp,sp BP salvare BP. . . . . . + 2 adresa de reveniremov ax,[bp+8];(AX)x + 4 adr_off var. b. . . . . . + 6 adr_seg var. bles di,[bp+4] + 8 valoarea var. a;(ES):(DI) adresa lui y. . . . . .

Page 6: Transferul parametrilor pentru proceduri

; în final se va descărca stivapop bpret 6

Pentru apelul acestei proceduri se va genera secvenţa următoare:mov ax,xpush ax ; depune în stivă valoarea parametrului xmov di, offset ypush ds ; depune adresa de segment a parametrului ypush di ; depune offsetul parametrului ycall modul ; apelul procedurii

În limbajul C, argumentele sunt puse în ordine inversă faţă de ordinea din lista de apel, în care apar (adică de la dreapta la stânga). Adresele de revenire pot fi de tip NEAR, ca în exemplul anterior, sau de tip FAR, în funcţie de modul de definire al procedurii.

Page 7: Transferul parametrilor pentru proceduri

Pointerii salvaţi în stivă, ca referinţă de parametru sau ca adresă de revenire respectă definiţia modelului de memorie stabilit în directiva model.

De exemplu stiva va arăta astfel, pentru un singur argument:

- modelul medium

push bp SP, BP salvare bp

mov bp,sp + 2 adr revenire - offset

mov di,[bp+6] adr revenire - segment

mov ax,[di] ; acces argument + 6 adresa argument

; tip cuvânt

- modelul large

push bp SP, BP salvare bp

mov bp,sp + 2 adr revenire - offset

les di,[bp+6] adr revenire - segment

mov ax,es:[di] ; acces argument + 6 adr argument – offset

; tip cuvânt adr arg. – segment

Page 8: Transferul parametrilor pentru proceduri

Pentru a nu modifica prea multe linii, în funcţie de modelul utilizat se pot utiliza directivele de asamblare condiţionată:

Ptr_FAR equ 1

. . . . . . . .

push bp

mov bp,sp

. . . . . . . .

ifdef Ptr_FAR

les di,[bp+6]

mov ax,es:[di]

else

mov di,[bp+6]

mov ax,[di]

endif

care dacă este definită va considera modelul large, iar dacă nu este definită va considera modelul medium.

Page 9: Transferul parametrilor pentru proceduri

Transferul parametrilor pentru subprograme în PASCAL şi C

program schimba_vectori;type

tip_vector = array [1..20] of real;var

vector1, vector2 : tip_vector;n,i : integer;

{$F+}{$L SCHIMB.OBJ}procedure InterSchimb (var v1, v2 : tip_vector; lung: word);

External;begin

{ se citesc : dimensiunea şi cei doi vectori }InterSchimb (vector1, vector2, sizeof(vector1));{ se afişează cei doi vectori după interschimbare }

end.

Page 10: Transferul parametrilor pentru proceduri

Procedura Interschimb (fişierul SCHIMB.OBJ) este următoarea:.model TPascal ; sau model large,Pascal.codestiva struc

val_BP dw ?IP_revdw ? ; sau adr_rev dd ?CS_rev dw ?lung dw ?offs_sir2 dw ? ; sau adr_sir1dd ?seg_sir2 dw ?offs_sir1 dw ? ; sau adr_sir2dd ?seg_sir1 dw ?

stiva endspublic InterShimbInterSchimb proc far

push bpmov bp, sppush ds ; se salvează registrele de lucru

Page 11: Transferul parametrilor pentru proceduri

push sipush es push dipush axpush cx ; urmează iniţializările de adrese şi contormov es, [bp].seg_sir1 ; sau les di, [bp].adr_sir1, saumov di, [bp].offs_sir1 ; les di, [bp+8]mov ds, [bp].seg_sir2 ; sau lds si, [bp].adr_sir2, saumov si, [bp].offs_sir2 ; lds si, [bp+12]mov cx, [bp].lung ; sau mov cx, [bp+6]

iar:mov al, ds:[si]xchg al, es:[di]mov ds:[si], alinc siinc diloop iar

Page 12: Transferul parametrilor pentru proceduri

pop cx ; refacerea registrelor salvate în stivăpop axpop dipop espop sipop dsret 10 ; se descarcă stiva de cei 10 octeţi

InterSchimb endpend

Linia de declarare a procedurii poate fi şi de forma:

InterSchimb proc far Ad_sir1:dword, Ad_sir2:dword, lung:word

iar în acest caz preluarea parametrilor se poate face mai simplu:

les di,Ad_sir2

lds si,Ad_sir1

mov cx,lung

Page 13: Transferul parametrilor pentru proceduri

;function Suma (sir: tip_vector; n:word):integer;External;.model large, Pascalpublic Suma.codeSuma proc far

adr_sir equ <[bp+8]>n equ <[bp+6]>s equ <[bp-2]> ; variabila locală pt. sumăpush bpmov bp, spsub sp, 2 ; rezervare spaţiu pt. variabila locală spush ds ; salvarea registrelor de lucrupush sipush cxlds si, adr_sir ; iniţializare adresă, contor, şi sumamov cx, nmov ax, 0mov s, ax

Page 14: Transferul parametrilor pentru proceduri

cld ; direcţia de parcurgere a şiruluijcxz gata ; dacă contorul a fost 0 s-a terminat

adun:lodswadd s, axloop adun

gata:mov ax, spop cxpop sipop dsmov sp, bp ; eliberarea spaţiului alocat variabilei locale s pop bpret 6 ; descărcarea stivei de parametrii

Suma endpend

Page 15: Transferul parametrilor pentru proceduri

Să considerăm, acum, şi cazul limbajului C. Vom rescrie funcţia suma(). Întrucât codul generat de compilatorul C transformă denumirile parametrilor funcţiei suma() adăugându-le caracterul ”_” la începutul lor, codul modulului apelat cu numele suma() se va numi de fapt _suma(); acelaşi lucru se întâmplă şi pentru ceilalţi parametri utilizaţi în ambele module.

.model small, C

.codepublic _suma

_suma procpush bpmov bp, sppush cxpush dspush simov cx, [bp+8]lds si, [bp+4]mov ax, 0 ; iniţializarea sumei cu 0

Page 16: Transferul parametrilor pentru proceduri

aduna:add ax, [si]add si, 2loop adunapop sipop dspop cxpop bpret

_suma endpend

Page 17: Transferul parametrilor pentru proceduri

#include <stdio.h>extern "C" int suma (int vect[], int dim);void main(void)

{int i, dim, vect[100];printf("Numarul de elemente din vector:");scanf("%d", &dim);printf("Elementele vectorului:\n");for (i=0; i<dim; i++)

{printf("vect[%d]=", i+1);scanf("%d", &vect[i]);}

printf("Suma elementelor vectorului este: %d\n",suma(vect, dim));

}

Page 18: Transferul parametrilor pentru proceduri

• Avantajele utilizării limbajului de asamblare- multe medii şi compilatoare LNI prezintă facilităţi de inserare de

linii scrise în limbaj de asamblare (C, Pascal, LabView, etc.).- componente ale sistemului de operare, şi ale altor aplicaţii, care

sunt considerate drept critice şi performante sunt realizate în LA.- programele sunt hibride: ele conţin linii scrise în LNI, dar pot

conţine şi linii în LA. - cunoaşterea mecanismelor fine ale procesorului, pentru a le folosi

în diferite aplicaţii. -> prog. mai eficiente în limbajele evoluate.- depanarea unui program poate trece de sursă, şi ajunge la

depanarea codului obiect, în care caz e necesar cunoaşterea LA. - motivul pentru care secvenţele critice se scriu în LA, şi nu în

limbaje de nivel înalt: compilatorul are "cunoştinţe limitate" asupra întregului program, dar el trebuie să genereze un set generalizat de instrucţiuni maşină, care vor lucra în toate situaţiile, dar nu vor fi optime în situaţii particulare.

Exemplu: Să se însumeze elementele unui vector, iar rezultatul să se depună într-o variabilă de memorie.

Page 19: Transferul parametrilor pentru proceduri

mov var_mem, 0 ; varianta LNImov si, lung_vect*2 - 2 ; ultimul element: vect + lungime*2 - 2

iar:mov ax, vect[si]add var_mem, axsub si, 2jnz iar

mov ax, 0 ; varianta LAmov si, lung_vect* - 2 ; ultimul element: vect + lungime*2 - 2

iar:add ax, vect[si]sub si, 2jnz iarmov var_mem, ax

Page 20: Transferul parametrilor pentru proceduri

Un alt exemplu, tot foarte simplu, dacă considerăm secvenţa generată, în C, pentru o secvenţă de program ce realizează rotirea biţilor dintr-o variabilă.

În timp ce secvenţei în C îi vor corespunde cam 7÷8 instrucţiuni limbaj de asamblare, celei de-a doua secvenţe, scrisă direct în asamblare, îi vor corespunde doar 2 instrucţiuni (respectiv: mov cl,n / rol ax,cl).

În C, pentru o rotire cu n poziţii stânga, trebuie scrise instrucţiunile pentru a realiza următoarele operaţii:

deplasare stânga cu n ranguri a variabilei:variabila1 = variabila << n;

deplasare dreapta cu “dimensiune_variabila – n” ranguri a variabilei:

variabila2 = variabila >> 8*sizeof variabila - n;rezultatul final se obţine printr-un sau logic între cele două

deplasări:variabila = variabila1 | variabila2;

Page 21: Transferul parametrilor pentru proceduri

Din punct de vedere al vitezei de execuţie sunt evidente trei lucruri:- instrucţiunile mai scurte, ca dimensiune, se execută mai rapid;- instrucţiunile fără referire la memorie se vor executa mai rapid;- instr. cu moduri de adresare complexe se vor executa mai lent;Din acest motiv se recomandă să păstraţi variabilele în registre.

nmov ax, 100hmov bx, 100hmov cx, 100hadd ax, 100h ; această secvenţă ocupă 12 octeţi în memorie

Putem reduce dimensiunea acestei secvenţe:mov ax, 100hmov bx, axmov cx, axadd ax, ax ; această secvenţă ocupă doar 6 octeţi

În cazul instrucţiunilor de salt condiţionat, programatorul poate determina care condiţie este mai des îndeplinită, şi să aranjeze progr. astfel încât condiţia care este îndeplinită mai des să fie pusă pentru continuarea progr., decât să se realizeze saltul condiţionat.

Page 22: Transferul parametrilor pentru proceduri

O altă observaţie utilă în scrierea programelor este legată de hazardurile ce pot să apară. Un tip de hazard este cel legat de date, care apare când operandul sursă al unei instrucţiuni a fost şi operand destinaţie al instrucţiunii anterioare:

mov dx, 400hmov bx, [200h] ; se încarcă în BX cuv. de la adresa 200hmov ax, [bx] ; se încarcă în AX cuv. de la adresa din BX

Este clar că în acest mod de scriere a secvenţei anterioare, instrucţiunea mov ax,[bx] va fi întârziată pe banda de asamblare, cu două cicluri, până când conţinutul lui BX va fi actualizat.

Se poate însă reduce efectul hazardului ce există în această secvenţă de cod, prin simpla rearanjare a instrucţiunilor:

mov bx, [200h] ; se încarcă în BX cuv. de la adresa 200hmov dx, 400hmov ax, [bx] ; se încarcă în AX cuv. de la adresa din BX

Dacă se mai inserează încă o instrucţiune între instrucţiunile mov bx,[200h] şi mov ax,[bx], atunci se poate elimina complet efectul hazardului.

Page 23: Transferul parametrilor pentru proceduri

• Definirea şi utilizarea de macroinstrucţiuni• O macroinstrucţiune (MI) reprezintă o secvenţă de instrucţiuni

căreia i se asociază un nume. Apariţia macroinstrucţiunii în textul programului este înlocuită, automat, de către asamblor, cu secvenţa de instrucţiuni asociată. Ea poate să fie parametrizată, adică poate fi definită în funcţie de o serie de parametrii formali, care sunt actualizaţi la utilizarea macroinstrucţiunii, fiind, deci, înlocuiţi cu parametrii actuali.

• Diferenţe între MI şi proc: codul obiect al unei proceduri apare o singură dată în program, în schimb codul obiect generat pentru o MI este repetat în program, ori de câte ori apare numele macroinstrucţiunii. Proc. reduce atât dimensiunea prog. sursă, cât şi pe cea a celui obiect, în timp ce MI nu reduce codul obiect, ci doar dimensiunea programului sursă. MI nu modifică timpul de execuţie al programului, pe când utilizarea procedurilor creşte timpul de execuţie.

• Utilizare macroinstrucţiunilor:- simplificarea şi reducerea secvenţelor de cod ce se repetă;- reducerea erorilor cauzate de codul repetitiv;- program în limbaj de asamblare mai uşor de urmărit.

Page 24: Transferul parametrilor pentru proceduri

< nume_macro > MACRO [ lista_parametri_formali ]< declaraţii/ corpul macroinstrucţiunii > [;comentarii]

ENDM

aduna macro t1,t2,sumamov ax, t1add ax, t2mov suma, ax

endm

Utilizarea se poate face astfel:aduna a, b, c mov ax, a

add ax, bmov c, ax

sauaduna bx,cx,dx mov ax, bx

add ax, cxmov dx, ax

Page 25: Transferul parametrilor pentru proceduri

• Dacă în definirea unei macro, se utilizează etichete, acestea trebuie declarate LOCAL. De exemplu dacă dorim să realizăm un ciclu, o secvenţă de forma:

mov cx, durata_cicluiar: loop iar

va genera erori de multidefinire a etichetei la utilizările ulterioare.delay macro durata

LOCAL iarpush cx ;; se salvează registrul CXmov cx, durata

iar: loop iar pop cxendm

LOCAL < lista_etichete >• Rolul său este de a declara simbolurile din listă ca locale pentru

fiecare apel. Directiva se poate utiliza numai în MI, şi precede instrucţiunile din corpul MI. Pentru aceste etichete asamblorul va genera, la expandare, nume de etichete succesive:??0000, ??0001, etc.

Page 26: Transferul parametrilor pentru proceduri

1) Calculul puterii întregi a unui număr întreg.putere macro numar, exponent

local iar, gatapush cx ; salvare (CX) şi (BX)push bxxor dx, dx ; rezultatul este returnat în (DX, AX)mov ax, 1 ; pregătire rezultat, dacă exponentul e 0mov cx, exponentjcxz gata ; dacă CX=0, puterea este 1mov bx, numar ; înmulţitorul în BX

iar: mul bxjc gata ; dacă apare eroare la *, se poziţionează

CFloop iar

gata: pop bx ; refacerea registrelor salvatepop cxendm ; programul ce utilizează această macro, va testa

; valoarea lui CF, dacă este 0 valoare corectă în; (DX,AX), dacă însă CF=1, a apărut depăşire

Page 27: Transferul parametrilor pentru proceduri

2) Înmulţirea unei valori cu 10.ori10 macro xlocal gata

push axpush bxmov ax, xshl ax, 1 ; * 2jc gatamov bx, ax shl ax, 1 ; * 4jc gatashl ax, 1 ; * 8jc gataadd ax, bxjc gata ; după utilizare macro ori10 se vamov x, ax ; testa indicatorul CF pentru a testa

gata: pop bx ; o eventuală depăşirepop axendm

Page 28: Transferul parametrilor pentru proceduri

• Macroinstrucţiunea de repetareREPT <expresie_contor>< corpul macroinstrucţiuni >ENDM

1) Alocarea unor valori consecutive la o anumită adresă:alocare macro tabela, lungime, vi, pas

tabela label bytevaloare = vi ; valoare iniţialărept lungime

valoare = valoare + pasdb valoare

endm endm

Utilizare:alocare tab1, 3, 0, 2 tab1 db 2, 4, 6alocare tab2, 10, 0, 1 tab2 db 1 , . . , 10

Page 29: Transferul parametrilor pentru proceduri

2) Generarea alfabetului, pentru litere mari, la o anumită adresă.generare_alfabet macro nume

nume label bytei = 0 rept 26

db 'A' + ii = i + 1

endmendm

alocare macro tab, dimtab label byte

i = 0rept dim

if (i gt 255)exitm ;; ieşire forţată din macro

else ;; înainte de execuţia tuturor

db i ;; instrucţiunilor secvenţeiendif

i = i + 1endm

endm

Page 30: Transferul parametrilor pentru proceduri

• Macroinstrucţiuni de repetare condiţionată (Indefinite RePeat)

IRP <nume>,<<lista>>< corpul macroinstrucţiunii >

ENDM <nume>, va fi înlocuit, în corpul MI cu valorile din <lista>.1) irp val, <1, 2, 3, 4, 5>

dw val*valendm

dw 1, 4, 9, 16, 25 2) suma label byte

irp x, <1, 3, 5, 7, 9>db x+x

endmsuma db 2, 6, 10, 14, 18

3) irp reg, <ax, cx, dx, bx, sp, bp, si, di>push reg

endm

Page 31: Transferul parametrilor pentru proceduri

IRPC (Indefinite RePeat Character) - rolul valorilor numerice din IRP este preluat de caractere.

1) irpc c, 12345dw c*c

endm2) Memorarea, la o adresă a unei valori în zecimal neîmpachetat:

scrie_val macro adresa, valoarelea si, adresairpc v, valoare

mov byte ptr [si], vinc si

endmendmPentru o utilizare de forma:

scrie_val adr1, 1997se va genera secvenţa, de cod, care va 1, 9, 9, 7, în format zec.

Dacă dorim să depunem o anumită secvenţă de caractere ASCII, se modifică doar linia:

mov byte ptr [si], '&v'

Page 32: Transferul parametrilor pentru proceduri

Utilizarea operatorilor &, % şi !Operatorul & este utilizat pentru substituirea simbolurilor, pe care le precede, cu valoarea numerică sau subşirul de caractere asociat simbolului respectiv (sau, altfel spus, concatenează valoarea asociată simbolului), în cazul utilizării simbolurilor respective ca argumente (parametrii) ale utilizării unei macroinstrucţiuni.

1) Declararea unor mesaje, iterative, în cadrul unui program:mesaj macro n

msg&n db 'mesaj nr.&n'endm

mesaj 5va genera: msg5 db 'mesaj nr.5'

mesaj 11va genera: msg11 db 'mesaj nr.11’

Dacă MI are 2 parametri sau mai mulţi, atunci ea se defineşte astfel:meserr macro n, o

err&n&o db 'eroare &n&&o'endm

Utilizarea acestei macro de forma: meserr 2,2va genera: err22 db 'eroare 22'

Page 33: Transferul parametrilor pentru proceduri

Dublarea caracterului &, a amânat evaluarea şirului &&o, pentru momentul evaluării MI IRP.

2) Compararea reg. AL cu caracterele 'a'..'f', şi execuţia pentru fiecare dintre ele unei anumite secvenţe (eticha, etichb, ..., etichf):irpc car, abcdef

cmp al, '&car'jz etich&car

endm

3) Definirea unei MI pentru rotirea conţinutului unei destinaţii, cu un număr de biţi şi o direcţie, specificate ca parametrii:rotire macro sens, nr_rot, dest

push cx ; salvare CX ; NU salv/reface CXmov cl, nr_rot ; sau reptnr_rot

ro&sens dest, cl ; ro&sens dest, 1

pop cx ; refacere CX ; endmendm

Page 34: Transferul parametrilor pentru proceduri

• Operatorul % realizează conversia simbolului care urmează, de la o valoare numerică la un şir de caractere, ce poate fi utilizat pentru a substitui un argument, pentru un apel de MI. Acest operator, de expansiune (%), forţează evaluarea imediată a expresiei ce urmează şi converteşte rezultatul expresiei la un şir de cifre.

mesaj5 macro nume,valdb '&nume = &val'

endmşi declaraţia:

const1 equ <LOW>pentru a defini mesajul

db 'const1 = LOW'se va utiliza MI anterioară, cu următorii parametrii:

mesaj5 const1, %const1Parantezele unghiulare < > se utilizează pentru a specifica că textul dintre ele este un singur şir. Aceste paranteze se utilizează şi când se doreşte transmiterea unui parametru actual, pentru un apel intern de macro (apelul unei macro în altă macro).

Page 35: Transferul parametrilor pentru proceduri

Generarea de mesaje multiple, care respectă o anumită regulă:meserr macro n

err&n db 'eroare&n’, 0Dh, 0Ah, ‘$'endmdiferr macro x

m = 0rept x

m = m + 1meserr %m

endmendm

Un apel al acestei macroinstrucţiuni, de forma:diferr 3

va genera mesajele:err1 db 'eroare1’, 0Dh, 0Ah, ‘$'err2 db 'eroare2’, 0Dh, 0Ah, ‘$'err3 db 'eroare3’, 0Dh, 0Ah, ‘$'

Page 36: Transferul parametrilor pentru proceduri

Un exemplu de utilizare pentru parantezele unghiulare:mesaj7 macro sir

db '&sir',0 ;; definire şir de caractere ASCIIZendm

apelul: mesaj7 <sir caractere>va genera db 'sir caractere',0

• Alt operator important pentru macroinstrucţiuni este operatorul literal, semnul exclamării (!). Acest simbol comandă asamblorului ignore interpretarea caracterului următor. Acest simbol poate fi utilizat atunci când este nevoie ca unul din următoarele caractere să fie inclus într-un şir de caractere, într-o MI: ! & > %

Dacă dorim să transmitem ca argument pentru o MI un şir de caractere ce conţine şi caracterul '>', atunci el va fi precedat de caracterul !, pentru a evita interpretarea lui '>' ca sfârşit de şir.

mesaj7 <a!>b>care va genera mesajul

db 'a>b',0

Page 37: Transferul parametrilor pentru proceduri

• Directive de asamblare condiţionată• Asamblorul permite utilizatorului să realizeze asamblarea doar a

unei anumite părţi a liniilor care compun modulul sursă. Este important de reţinut că aceste directive evaluează expresiile lor la momentul asamblării şi nu la cel al execuţiei programului.

• Motivele asamblării condiţionate:- un program general trebuie 'adaptat' pentru o anumită aplicaţie, funcţie de parametrii actuali incluzându-se anumite module, sau dimensionându-se zone de memorie, corespunzător aplicaţiei; altfel, prin includerea tuturor modulelor sau prin dimensionarea la maxim a zonelor de memorie, indiferent de aplicaţie, se ajunge la dimensionări neeconomice;- includerea doar a unora dintre instrucţiunile prezente, în textul sursă, datorită unor diferenţe între procesoarele aceleiaşi familii (286, 386, 486, etc.).

• Directivele de asamblare condiţionată sunt importante deoarece permit generarea de diferite coduri obiect pentru diferite medii de operare şi diferite situaţii. Pe durata asamblării, programatorul poate alege condiţionat dacă asamblorul să asambleze, de exemplu, versiunea pentru 386 sau pentru Pentium.

Page 38: Transferul parametrilor pentru proceduri

Sintaxa pentru directiva IF este următoarea:IF condiţie ; condiţia este o expresie ce poate

secvenţa 1 ; fi evaluată, în momentul asamblării[ELSE ; la o constantă 'TRUE' sau 'FALSE'

secvenţa 2] ; clauza ‘else’ este opţionalăENDIF

În mod asemănător sunt definite directivele:IFE exp ; dacă expresia este zero se execută secv1

; altfel se execută secv2IFB arg ; dacă argumentul este blanc (' ') se

; executa secv1, altfel se execută secv2IFNB <arg ; adică argumentul <> blanc se execută secv1,

; altfel, argument =' ', execută secvenţa 2.IFDIF <arg1>, <arg2> ; se compară cele două argumente,

; (senzitiv la tipul literelor: mari şi mici), şi; dacă sunt diferite execută secv1, altfel secv2

IFDIFI <arg1>, <arg2>; este asemănătoare cu dir. anterioară, ; cu deosebirea că ignoră tipul literelor.

Page 39: Transferul parametrilor pentru proceduri

IFIDN <arg1>, <arg2> ; se compară cele două argumente, ; (senzitiv la tipul literelor: mari şi mici), şi; dacă sunt identice exec. secv1, altfel secv2

IFIDNI <arg1>, <arg2> ; este asemănătoare cu dir. anterioară, ; cu deosebirea că ignoră tipul literelor.

IFDEF <argument> ; dacă simbolul prezent ca arg. este; definit execută secv.1, altfel secv.2

IFNDEF <argument> ; dacă simbolul prezent ca arg. nu ; este definit execută secv.1.

tip_car macro car ; utilizare:ifb <car> tip_car 'x' ;generează

mov dl, ' ' mov dl, 'x'else mov ah, 2mov dl, car int 21h

endif tip_car ; va generamov ah, 2 mov dl, ' 'int 21h mov ah, 2

endm int 21h

Page 40: Transferul parametrilor pentru proceduri

MI recursivă care depune registre în stivă; depunerea va înceta când în lista registrelor apare blancul.push_reg macro r1, r2, r3 ; utilizare:

ifnb <r1> push_reg ax, bx, cxpush r1 push axpush_reg r2, r3 push bx

endif push cxendmMI ce generează diferite instrucţiuni în funcţie de un param.movt macro tip

ifidn <tip>, <B> ; utilizare: movt Drep movsd ; sau: movt Wexitm ; sau: movt

endififidn <tip>, <W>

rep movswelse rep movsb ; implicit, dacă nu are paramteruendif

endm

Page 41: Transferul parametrilor pentru proceduri

• Directive pentru generarea condiţionată a erorilor

În conjuncţie cu directivele de asamblare condiţionată, există un set de directive pentru generarea de mesaje de eroare, în aceleaşi condiţii ca primele. Asamblorul generează mesajul de eroare la întâlnirea unei astfel de directive, dacă este îndeplinită condiţia respectivă. Ele sunt utilizate, cu predilecţie, în cadrul MI.

.ERR - generează mesaj de eroare, de exemplu:

if var1 lt var2

.err ; va genera mesaj dacă: var1 < var2

endif

.ERRE expresie

.ERRNZ expresie

.ERRB <argument>

.ERRNB <argument

.ERRDIF<arg1>,<arg2>

.ERRDIFI <arg1>,<arg2>

Page 42: Transferul parametrilor pentru proceduri