Vous êtes sur la page 1sur 25

Asm 1 Adrese Orice adresa este formata din doua componente: segment si offset (deplasament), notatia uzuala fiind

segment:offset. Pentru partea de offset exista mai multe variante: Constanta numerica. Exemplu: 1!!" #aloarea unui registru general pe $% &iti. Exemplu: EA'" (se poate scrie si cu litere mici) (uma dintre valoarea unui registru general pe $% &iti si o constanta. Exemplu: E)'*+" (uma a doi registri generali pe $% &iti. Exemplu: EC'*E(," Com&inatia celor % variante anterioare: suma a % registri si a unei constante. Exemplu: E-'*E)P*1." (uma a % registri, dintre care unul inmultit cu %, ., sau /, la care se poate aduna o constanta. Exemple: EA'*E-,0%", EC'*E-'0.*+" ,nstructiunea de atri&uire: mov (intaxa: mov destinatie, sursa Efect: pune in destinatie valoarea din sursa. -estinatia, respectiv sursa, pot fi: registru, registru. Exemple: mov eax, ebx;, mov al, bh; registru, adresa de memorie. Exemplu: mov bl, [eax]; adresa de memorie, registru. Exemplu: mov [esi], esx; registru, constanta numerica. Exemplu: mov ah, 0; memorie, constanta numerica. Exemplu: mov [eax], 3; Ex. 1: 1include 2stdio.34 void main()5 6asm5 mov eax, !7 mov a3, 17 8 8 Ex. %: 1include 2stdio.34 void main()5 int i 9 !7 6asm5 mov ax, i7

8 8 -imensiunea operanzilor: mov &:te ptr eax", +7 ;;afecteaza 1 octet mov <ord ptr eax", +7 ;;afecteaza % octeti mov d<ord ptr eax", +7 ;;afecteaza . octeti (dou&le <ord) ,nstruc=iunea add (intaxa: add op1, op2 Efect: op1 9 op1 * op% Ex. 1: 1include 2stdio.34 void main()5 int a91!7 6asm 5 add a,+ 8 printf(>?d@n>,a)7 8 Ex. %: 1include 2stdio.34 void main()5 6asm 5 mov eax,!xAAAAAAAA7 add eax,%7 ;; rezultatul este !x1!!!!!!!17 necesita $$ &iti. ;; setare carr: mov eax,!7 mov ax, !xAAAA7 add ax, %7 ;; doar ax se modificaB ;; desi rezultatul este !x1!!!1, ;; al 1CDlea &it din eax nu se modifica. ;; se seteaza carr: 8 printf(>?d@n>,c)7 8 ,nstruc=iunea su& (intaxa: sub op1, op2 Efect: op1 9 op1 D op%

Ex. 1: 1include 2stdio.34 void main() 5 int a91!,&91.7 6asm 5 mov eax,& su& a,eax 8 printf(>?d@n>,a)7 8 ,nstruc=iuni &ooleene: AE-, OF, 'OF, EOG (intaxa: and destinatie, sursa or destinatie, sursa xor destinatie, sursa not destinatie ,nstruc=iunile and, or, xor modific indicatorul !"# Htilitatea principalI a acestor instruc=iuni este in lucrul cu mIJti. -e exemplu, dacI ne intereseazI valoarea &itului al +Dlea din registrul ax, este suficient sI se execute and intre ax Ji valoarea (scrisa &inar) !!!!!!!!!!!1!!!! (aceasta se numeJte mascI). Fezultatul opera=iei va fi ! (iar indicatorul KEFO va deveni 1) dacI &itul al +Dlea din ax are valoarea !, respectiv va fi diferit de ! (iar indicatorul KEFO va deveni !) dacI &itul al +Dlea din ax are valoarea 1. -ezavantaLul a&ordIrii de mai sus este acela cI instruc=iunea and modificI valoarea primului operand, plasind acolo rezultatul opera=iei. ,nstruc=iunea test are acelaJi efect ca Ji and (executI AE- intre &i=ii celor doi operanzi, modificI la fel indicatorul KEFO), dar nu alterea$ valoarea primului operand. -e exemplu: test ax, !x!!1! ;; &inar: !!!!!!!!!!!1!!!! modificI indicatorul KEFO ca Ji and ax, !x!!1! fIrI a altera valoarea din ax. Asm % ,nstruc=iunea mul M Nnmul=ire de numere fIrI semn (intaxa: mul op

Efect: destinatie%implicita & operand%implicit ' op Opera=ia de Nnmul=ire este o opera=ie &inarI. -in moment ce la instruc=iunea mul se precizeazI un singur operand, este evident cI celalalt operand va fi implicit. Operandul implicit depinde de dimensiunea operandului explicit op (dupI cum Jtim Ji de la celelalte instruc=iuni studiate, operanzii tre&uie sI ai&I aceeaJi dimensiune). On ta&elul de mai Los sunt preciza=i operanzii implici=i pentru fiecare din dimensiunile posi&ile ale operandului explicit. On plus, tre&uie o&servat faptul cI reprezentarea rezultatului opera=iei de Nnmul=ire poate avea lungime du&lI fa=I de lungimea operanzilor. -e exemplu, Nnmul=ind urmItoarele % numere reprezentate pe cPte / &i=i, o&=inem un rezultat reprezentat pe 1Q &i=i: 1!11!111 0 11!1!!1! DDDDDDDDDDDDDDDD ! 1!11!111 1!11!111 1!11!111 1!11!111 DDDDDDDDDDDDDDDD 1!!1!11!!!!1111! -eci dimensiunea destina=iei implicite tre&uie sI fie du&lul dimensiunii operanzilor. Ga&elul de mai Los prezintI operanzii implici=i Ji destina=iile implicite pentru diversele dimensiuni ale operandului implicit: -imensiune operand explicit Operand implicit -estina=ie implicitI 1 octet al ax % octe=i ax (dx, ax) . octe=i eax (edx, eax) Operandul explicit nu poate fi constant numeric: mul 1!7 ;;EFOAFE mul &:te ptr %7 ;;EFOAFE El tre&uie sI fie ori un registru de date (al, e&x, ...), ori o adres de memorie. -acI adresa de memorie nu este datI prin numele sim&olic (de exemplu, numele unei varia&ile declarate Nn programul C ce NncapsuleazI codul asm), ci prin modurile de adresare discutate anterior, tre&uie precizatI dimensiunea Nn octe=i a zonei de

memorie ce con=ine respectivul operand explicit, pentru a se putea sta&ili operandul implicit Ji destina=ia implicitI. -e exemplu: mul b(te ptr [ebp ) *] : operandul explicit se aflI Nn memorie la adresa e&p D ." Ji are dimensiunea de 1 octet (valoarea efectivI este cea din octetul de la aceasta adresa) mul +ord ptr [ebp ) *] : operandul explicit se aflI la adresa e&p D ." Ji are dimensiunea de % octe=i (valoarea efectivI este cea compusI din primii % octe=i de la aceasta adresa) mul d+ord ptr [ebp ) *] : operandul explicit se aflI la adresa e&p D ." Ji are dimensiunea de . octe=i (valoarea efectivI este cea compusI din primii . octe=i de la aceasta adresa) CPteva exemple: linia de cod mul bl va avea urmatorul efect: se calculeazI rezultatul Nnmul=irii dintre al Ji bl (bl are dimensiunea de 1 octet, deci operandul implicit la Nnmul=ire este al) acest rezultat se pune Nn ax(care este destina=ia implicitI pentru Nnmul=iri cu operandul explicit op de 1 octet Rai concret, mul bl 294 ax & al ' bl linia de cod mul bx va avea urmatorul efect: se calculeazI rezultatul Nnmul=irii dintre ax Ji bx (bx are dimensiunea de % octe=i, deci operandul implicit la Nnmul=ire este ax) acest rezultat se pune Nn ,dx,ax- astfel: primii % octe=i (cei mai semnificativi) din rezultat vor fi plasa=i Nn dx, iar ultimii % octe=i (cei mai pu=in semnificativi) Nn ax 1. rezultatul Nnmul=irii este, de fapt, dx'2 / ax -esigur, acest rezultat pe . octe=i ar fi NncIput Nn eax. (e folosesc NnsI regiJtrii ,dx,ax- pentru compati&ilitatea cu maJinile mai vec3i, pe 1Q &i=i. Exemplu de cod: 1include 2stdio.34 void main()5 6asm 5 mov ax, Q!!!!7 ;;in &aza 1Q: EAQ! mov &x, Q!!!!7 ;;in &aza 1Q: EAQ! mul &x7 ;;rezultatul inmultirii este $Q!!!!!!!!7 ;;in &aza 1Q: -QS$A.!!, plasat astfel: ;;in registrul dx D partea cea mai semnificativa: -QS$ ;;in registrul ax D partea cea mai putin semnificativa: A.!!

8 8 linia de cod mul ebx va avea urmatorul efect: se calculeazI rezultatul Nnmul=irii dintre eax Ji ebx (ebx are dimensiunea de . octe=i, deci operandul implicit la Nnmul=ire este eax) acest rezultat se pune Nn ,edx,eax- astfel: primii . octe=i (cei mai semnificativi) din rezultat vor fi plasa=i Nn edx, iar ultimii . octe=i (cei mai pu=in semnificativi) Nn eax 32 rezultatul Nnmul=irii este, de fapt, edx'2 / eax Exemplu de cod: 1include 2stdio.34

void main()5 6asm 5 mov eax, Q!!!!7 ;;in &aza 1Q: !!!!EAQ! mov e&x, Q!!!!7 ;;in &aza 1Q: !!!!EAQ! mul e&x7 ;;rezultatul inmultirii este $Q!!!!!!!!7 ;;in &aza 1Q: -QS$A.!!, plasat astfel: ;;in edx D partea cea mai semnificativa: !!!!!!!! ;;in eax D partea cea mai putin semnificativa: -QS$A.!! 8 8 ,nstruc=iunea imul M Nnmul=ire de numere cu semn (,nteger RHTtipl:) (intaxa: imul op -upI cum am precizat mai sus, la instruc=iunea mul operanzii sunt considera=i numere fIrI semn. Aceasta NnseamnI cI se lucreazI cu numere pozitive, iar &itul cel mai semnificativ din reprezentare este prima cifrI a reprezentIrii &inare, nu &itul de semn. Pentru opera=ii de Nnmul=ire care implicI numere negative existI instruc=iunea imul (este nevoie de douI instruc=iuni distincte deoarece, spre deose&ire de adunare sau scIdere, agoritmul de Nnmul=ire este diferit la numerele cu semn). Ceea sDa prezentat la mul este vala&il Ji pentru imul. -iferen=a este aceea cI numerele care au &itul cel mai semnificativ 1 sunt considerate numere negative, reprezentate Nn complement fa=I de %. Exemplu: void main()5 6asm 5 mov ax, !xAAAA7 mov &x, !xAAAE7

mul &x7

;;rezultatul inmultirii numerelor AAFA (ERE: ;;Q++$+ 0 Q++$. 9 .%S.CC!QS!7 ;;in &aza 1Q: AAA-!!!%, plasat astfel: ;;in dx D partea cea mai semnificativa: AAA;;in ax D partea cea mai putin semnificativa: !!!%

mov ax, !xAAAA7 mov &x, !xAAAE7 imul &x7 ;;rezultatul inmultirii numerelor CH (ERE: ;;D1 0 D% 9 %7 ;;in &aza 1Q: !!!!!!!%, plasat astfel: ;;in dx D partea cea mai semnificativa: !!!! ;;in ax D partea cea mai putin semnificativa: !!!% 8 8 Exerci=iu: Aie urmItorul program care calculeazI factorialul unui numIr. (I se NnlocuiascI linia de cod din interiorul &uclei for (f 9 f 0 i) cu un &loc de cod asm, cu o&=inerea aceluiaJi efect. Pentru simplificare, vom considera cI rezultatul nu depIJeJte . octe=i. 1include 2stdio.34 void main()5 unsigned int n 9 1!, i, f 9 17 for(i917i29n7i**)5 f 9 f 0 i7 8 printf(>?u@n>,f)7 8 OmpIr=irea ,nstruc=iunea div M NmpIr=ire de numere fIrI semn (intaxa: div op Efect: cat%implicit, rest%implicit & deimpartit%implicit : op ,nstruc=iunea div corespunde opera=iei de NmpIr=ire cu rest. Ca Ji la Nnmul=ire, operandul implicit (deNmpIr=itul) Ji destina=ia implicitI (cPtul Ji restul) depind de dimensiunea operandului explicit op (NmpIr=itorul): -imensiune operand explicit -eNmpIr=it CPt Fest (NmpIr=itor)

1 octet ax al a3 % octe=i (dx, ax) ax dx . octe=i (edx, eax) eax edx (A se o&serva similaritatea cu instruc=iunea de Nnmul=ire.) On toate cazurile, cPtul este depus Nn LumItatea cea mai pu=in semnificativI a deNmpIr=itului, iar restul Nn cea mai semnificativI. Acest mod de plasare a rezultatelor permite reluarea opera=iei de nmpIr=ire nn &uclI, dacI este cazul, fIrI a mai fi nevoie de opera=ii de transfer suplimentare. Analog cu Nnmul=irea, operandul explicit (NmpIr=itorul) poate fi un registru sau o loca=ie de memorie, dar nu o constantI: div e&x div cx div d3 div &:te ptr ..." div <ord ptr ..." div d<ord ptr ..." div &:te ptr 1! ;; eroare Opera=ia de NmpIr=ire ridicI o pro&lemI care nu se NntPlneJte Nn alte pIr=i: NmpIr=irea la !: 1include 2stdio.34 void main()5 6asm 5 mov eax, 1 mov edx, 1 mov e&x, ! div e&x 8 8 Programul va semnala o eroare la execu=ie (integer divide &: zero) Ji va fi terminat for=at. EfectuPnd urmItoarea modificare: 1include 2stdio.34 void main()5 6asm 5 mov eax, 1 mov edx, 1 mov e&x, 1 ;;1 in loc de !

div e&x 8 8 se o&=ine o altI eroare la execu=ie: integer overflo<. Rotivul este acela cI se NncearcI NmpIr=irea numIrului !x1!!!!!!!1 la 1, cPtul fiind !x1!!!!!!!1. Acest cPt tre&uie depus Nn registrul eax, NnsI valoarea lui depIJeJte valoarea maximI ce poate fi pusI Nn acest registru, adicI !xAAAAAAAA. Rai concret, Nn cazul Nn care cPtul nu Nncape Nn registrul corespunzItor, se o&=ine eroare: (edx0%$% * eax) ; e&x U %$% 294 edx0%$% * eax U e&x0%$% 294 eax U (e&x D edx) 0 %$% 294 ebx 0 edx Cu alte cuvinte, vom o&=ine cu siguran=I eroare dacI NmpIr=itorul este mai mic sau egal cu partea cea mai semnificativI a deNmpIr=itului. Pentru a evita terminarea for=atI a programului, tre&uie verificatI aceastI situa=ie Nnainte de efectuarea NmpIr=irii. ,nstruc=iunea idiv M NmpIr=ire de numere cu semn (intaxa: idiv op idiv func=ioneazI ca Ji div, cu diferen=a cI numerele care au &itul cel mai semnificativ 1 sunt considerate numere negative, reprezentate Nn complement fa=I de %. Exemple de cod 1include 2stdio.34 void main()5 6asm 5 mov ax, $+7 mov dx, !7 ;;nu tre&uie uitata initializarea lui (e)dxB ;;(in general, initializarea partii celei mai ;; semnificative a deimpartitului) mov &x, C7 div &x7 ;;rezultat: ax devine +, adica !x!!!+ (catul) ;; dx devine ! (restul) mov ax, $+7 mov dx, !7 mov &x,C idiv &x ;; acelasi efect, deoarece numerele sunt pozitive

mov ax, D$+7 ;;in 3exa (complement fata de %): AA-mov dx, !7 mov &x,C div &x ;;deimpartitul este (dx, ax), adica !!!!AA-;;in &aza 1!: Q++!1 ;;rezultat: ax devine !x$$%C, adica 1$1!! (catul) ;; dx devine !x!!!1 (restul) mov ax, D$+7 ;;in 3exa (complement fata de %): AA-mov dx, !7 mov &x,C idiv &x ;;deimpartitul este (dx, ax), adica !!!!AA-;;este un mumar pozitiv, adica, in &aza 1!, Q++!1 ;;rezultat: ax devine !x$$%C, adica 1$1!! (catul) ;; dx devine !x!!!1 (restul) ;;(efectul este acelasi ca la secventa de mai sus) mov ax, D$+7 ;;in 3exa (complement fata de %): AA-mov dx, D17 ;;in 3exa (complement fata de %): AAAA mov &x,C idiv &x ;;deimpartitul este (dx, ax), adica AAAAAA-;; D numar negativ, reprezentat in complement fata de % ;;in &aza 1!: D$+ ;;rezultat: ax devine !xAAAS, adica D+ (catul) ;; dx devine ! (restul) mov ax, D$+7 ;;in 3exa (complement fata de %): AA-mov dx, D17 ;;in 3exa (complement fata de %): AAAA mov &x,C div &x ;;deimpartitul este (dx, ax), adica AAAAAA-;; D numar pozitiv (deoarece folosim div) ;; in &aza 1!: .%S.SQC%Q1 ;;rezultat: EFOAFE, deoarece AAAA 4 !!!C, ;; catul (Q1$+QQC+1, adica %.S%.S1A) nu incape in ax 8 8 Exerci=iu

Aie urmItorul program. (I se NnlocuiascI liniile . Ji + cu un &loc de cod asm, cu o&=inerea aceluiaJi efect. 1. 1include 2stdio.34 %. void main()5 $. unsigned a9+!!!!C,&91!,c,d7 .. c9a;&7 +. d9a?&7 Q. printf(>?u ?u@n>,c,d)7 C.8 ,nstruc=iuni de deplasare (unt instruc=iuni care permit deplasarea &i=ilor Nn cadrul operanzilor cu un numIr precizat de pozi=ii. -eplasIrile pot fi aritmetice sau logice. -eplasIrile aritmetice pot fi utilizate pentru a Nnmul=i sau NmpIr=i numere prin puteri ale lui %. -eplasIrile logice pot fi utilizate pentru a izola &i=i Nn octe=i sau cuvinte. -intre modificIrile pe care deplasIrile le fac asupra indicatorilor: Carr: Alag (CA) 9 ultimul &it deplasat Nn afara operandului destina=ie7 (ign Alag ((A) 9 &itul cel mai semnificativ din operandul destina=ie7 Kero Alag (KA) 9 1 dacI operandul destina=ie devine !, ! altfel. O ilustrare a deplasIrii logice la stPnga cu o pozi=ie: ,nstruc=iunile de deplasare sunt: shr dest, count shl dest, count sar dest, count sal dest, count unde: dest semnificI destina=ia a cIrei valoare va fi modificatI7 poate fi registru sau loca1ie de memorie: shl eax, 1 shl dx, $ shl &:te ptr ...", % count precizeazI cu cNte pozi=ii se face deplasarea7 poate fi constant numeric sau registrul cl: shl e&x, cl ,nstruc=iunea s3r ((Vift Fig3t) (intaxa: shr dest, count

Efect: deplasarea la dreapta a &i=ilor din dest cu numIrul de pozi=ii precizat de count7 completarea la stPnga cu !7 plasarea Nn Carr: a ultimului &it ieJit. Exemplu: mov &l, $$7 ;;&inar: !!1!!!!1 s3r &l, $7 ;;&l devine !!!!!1!! ;;Carr: devine ! s3r &l, $ ;;&l devine !!!!!!!! ;;Carr: devine 1 ,nstruc=iunea s3l ((Vift Teft) (intaxa: shl dest, count Efect: deplasarea la stPnga a &i=ilor din dest cu numIrul de pozi=ii precizat de count7 completarea la dreapta cu !7 plasarea Nn Carr: a ultimului &it ieJit. Exemplu: mov &l, $$7 ;;&inar: !!1!!!!1 s3l &l, $7 ;;&l devine !!!!1!!! ;;Carr: devine 1 s3l &l, 1 ;;&l devine !!!1!!!! ;;Carr: devine ! ,nstruc=iunea sar ((3ift Arit3metic Fig3t) (intaxa: sar dest, count Efect: deplasarea la dreapta a &i=ilor din dest cu numIrul de pozi=ii precizat de count7 &itul cel mai semnificativ NJi pIstreazI vec3ea valoare, dar este Ji deplasat spre dreapta (extensie de semn)7 plasarea Nn Carr: a ultimului &it ieJit. Exemplu: mov &l, D$Q7 ;;&inar: 11!111!! sar &l, %7 ;;&l devine 1111!111 ;;Carr: devine ! Gre&uie men=ionat cI sar nu furnizeazI aceeaJi valoare ca Ji idiv pentru operanzi ec3ivalen=i, deoarece idiv trunc3iazI toate cPturile cItre !, Nn timp ce sar trunc3iazI cPturile pozitive cItre ! iar pe cele negative cItre infinit negativ. Exemplu mov a3, DC7 ;;&inar: 11111!!1 sar a3, 17 ;;teoretic, ec3ivalent cu impartirea la % ;;rezultat: 111111!!, adica D. ;;idiv o&tine catul D$ ,nstruc=iunea sal ((3ift Arit3metic Teft) (intaxa: sal dest, count Efect: identic cu shl.

Asm $ EATAW( Este un registru de $% de &iti care indica >starea> procesorului la un moment dat. -oar o parte din cei $% de &iti sunt folositi pentru a furniza informatii despre rezultatul ultimei operatii executate de procesor. )itii din EATAW( se mai numesc si indicatori. -intre acestia, amintim: CA D carr: flag (transport) D are valoarea 1 (este setat) daca dupa ultima operatie a aparut transport, ! (nu este setat) altfel. PA D parit: flag (paritate) D are valoarea 1, daca numarul de &iti de 1 din rezultatul ultimei operatii este par. KA D zero flag D are valoarea 1, daca rezultatul ultimei operatii a fost !. (A D sign flag (semn) D are valoarea 1, daca rezultatul ultimei operatii a fost negativ (&itul cel mai semnificativ este 1). OA D overflo< flag (depasire) D are valoarea 1, daca ultima operatie a produs depasire aritmetica. ,nstruc=iuni de salt ,nstruc=iunile de salt modificI valoarea registrului contor program (E,P), astfel NncPt urmItoarea instruc=iune care se executI sI nu fie neapIrat cea care urmeazI Nn memorie. (unt utile pentru implementarea, la nivel de lim&aL de asam&lare, a structurilor de control (testIri sau &ucle). (alturile pot fi: necondi=ionate: instruc=iunea 2mp condi=ionate: instruc=iuni de forma 23condi1ie4 (intaxa: instructiune%salt adresa #om considera Nn continuare doar cazul Nn care adresa este o constantI referitI de o etic3etI. Exemplul de mai Los ilustrazI modul de definire Ji utilizare a etic3etelor: 1include 2stdio.34 void main()5 int i7 6asm5 mov i, 117 Lmp etic3eta7

su& i, $7 ;; aceasta instructiune nu se executa etic3eta: add i, .7 8 printf (>?d@n>, i)7 8 (altul necondi=ionat (instruc=iunea Lmp) Eu introduce o ramifica=ie Nn program, neexistNnd variante de execu=ie. Este util, folosit NmpreunI cu salturi condi=ionate, pentru reluarea unei secven=e de de cod NntrDo &uclI, aJa cum se va vedea NntrDun exemplu ulterior. (alturi condi=ionate ,ntroduc o ramifica=ie Nn program, deoarece avem douI variante: condi=ia de salt este adevIratI M se face saltul la adresa indicatI condi=ia de salt este falsI M se continuI cu instruc=iunea urmItoare din memorie ca Ji cum nu ar fi existat instruc=iune de salt. ,nstruc=iuni care testeazI indicatorii individuali Cele mai utile la acest nivel sunt cele care testeazI indicatorii: Carr:, Overflo<, (ign, Kero. Pentru fiecare indicator existI douI instruc=iuni de salt condi=ionat: una care face saltul cPnd indicatorul testat are valoarea 1 Ji una care face saltul cPnd are valoarea !. indicator testat salt pe valoarea 1 salt pe valoarea ! Carr: Lc Lnc Overflo< Lo Lno Kero Lz Lnz (ign Ls Lns Exemplu: 1include 2stdio.34 void main()5 int a, &, s9!7 printf(>a9>)7 scanf(>?x>, Xa)7 printf(>&9>)7 scanf(>?x>, X&)7 6asm5 mov eax, a7 add eax, &7 Lc semnaleaza6depasire7 ;;in #isual C**,

;; putem sari la o etic3eta din codul C mov s, eax7 Lmp afiseaza6suma7 ;;sau din alt &loc asm

8 semnaleaza6depasire: printf (>(Da produs depasireB@n>)7 return7 6asm5 afiseaza6suma: 8 printf (>?x * ?x 9 ?x@n>, a, &, s)7 8 ,nstruc=iuni corespunzItoare operatorilor rela=ionali On practicI, utilizIm mai des ramificIri dictate de operatori rela=ionali: 2, 29, B9, etc. On acest sens este utilI instruc=iunea de comparare cmp: cmp func=ioneazI ca Ji sub (aceleaJi restric=ii pentru operanzi, aceia5i indicatori modifica1i), NnsI nu modificI primul operand (destina=ia). Prin verificarea indicatorilor se poate sta&ili Nn urma aceste opera=ii rela=ia dintre operanzi. ,nstruc=iunile care fac aceste verificIri sunt: rela=ie instruc=iune Comentariu op1 2 op% L& >Yump if )elo<> op1 29 op% L&e >Yump if )elo< or EZual> op1 4 op% La >Yump if A&ove> op1 49 op% Lae >Yump if A&ove or EZual> pentru numere fr semn, respectiv rela=ie instruc=iune Comentariu op1 2 op% Ll >Yump if Tess t3an> op1 29 op% Lle >Yump if Tess t3an or EZual> op1 4 op% Lg >Yump if Wreater t3an> op1 49 op% Lge >Yump if Wreater t3an or EZual> pentru numere cu semn. (unt necesare instruc=iuni diferite pentru numere fIrI semn, respectiv cu semn, deoarece indicatorii ce tre&uie verifica=i diferI. -e exemplu, comparPnd !!1!!11! Ji 11!!11!1, ar tre&ui sI o&=inem rela=ia !!1!!11! 2 11!!11!1 dacI sunt numere fIrI semn, Ji !!1!!11! 4 11!!11!1 dacI sunt numere cu semn. ,ndependent de statutul &itului celui mai semnificativ (semn sau cifrI) func=ioneazI instruc=iunile:

rela=ie instruc=iune Comentariu op1 99 op% Le >Yump if EZual> (identic cu Lz) op1 B9 op% Lne >Yump if Eot EZual> (identic cu Lnz)

Asm . Tucrul cu stiva. Apelul func=ilor Tucrul cu stiva Procesorul foloseJte o parte din memoria FAR pentru a o accesa dupI o disciplinI de tip T,AO (ca Nn cazul unei structuri de stivI). -upI cum se Jtie, singura informa=ie fundamentalI pentru gestiunea stivei este v6rful acesteia. On cazul procesorului, adresa la care se aflI vPrful stivei este memoratI Nn perec3ea de regiJtri 77 Ji !787 deoarece regiJtrii segment au, pe maJinile pe $% de &i=i, doar scop de >validare> a adresei, vom lucra Nn continuare numai cu E(P. ,nstruc=iunile care permit lucrul cu stiva sunt push Ji pop. ,nstruc=iunea pus3 FealizeazI introducerea unei valori Nn stivI. (intaxa: push operand7 Operandul poate fi registru, loca=ie de memorie sau constantI numericI. (tiva lucreazI doar cu valori de % sau . octe=i, pentru uniformitate preferPnduDse numai operanzi de . octe=i (varianta cu % se pIstrazI pentru compati&ilitate cu procesoarele mai vec3i). Exemple: pus3 eax pus3 dx pus3 d<ord ptr ..." pus3 <ord ptr ..." pus3 d<ord ptr + pus3 <ord ptr 1. ,ntroducerea valorii Nn stivI se face astfel: se scade din E(P dimensiunea, Nn octe=i, a valorii care se vrea depusa Nn stivI, dupa care procesorul scrie valoarea operandului la adresa indicatI de registrul E(P (vPrful stivei)7 dimensiunea poate fi % sau . (se o&servI cI se avanseazI >Nn Los>, de la adresele mai mari la adresele mai mici)7 Nn acest mod, vPrful stivei este pregItit pentru urmItoarea opera=ie de scriere. -e exemplu, instruc=iunea pus3 eax7 ar fi ec3ivalentI cu:

su& esp, .7 mov esp", eax7 Prin folosirea lui push Nn locul secven=ei ec3ivalente se reduce, NnsI, riscul erorilor. ,nstruc=iunea pop Extrage vPrful stivei NntrDun operand destina=ie. (intaxa: pop operand7 Operandul poate fi registru sau loca=ie de memorie, de % sau . octe=i. Exemple: pop eax pop cx pop d<ord ptr ..." pop <ord ptr ..." Extragerea valorii din stivI se face prin depunerea Nn destina=ie a valorii aflate Nn vPrful stivei (la adresa E(P") Ji adunarea, la E(P, a numIrului de octe=i ai operandului (acesta indicI, practic, numIrul de octe=i scoJi din stivI). Folul stivei Folul stivei procesorului este acela de a stoca informa=ii cu caracter temporar. -e exemplu, dacI avem nevoie sI folosim un registru pentru niJte opera=ii, dar nu avem la dispozi=ie nici un registru a cIrui valoare curentI sI ne permitem sI o pierdem, putem proceda ca mai Los: pus3 eax7 ;;se salveaza temporar valoarea lui eax pe stiva ... ;; utilizare eax pop eax ;;restaurare #aria&ilele locale (cu excep=ia celor statice) sunt plasate de asemenea Nn stivI (deoarece au caracter temporar: sunt create la intrarea Nn func=ie Ji distruse la ieJire). On lucrul cu stiva, instruc1iunile de introducere 9n stiv trebuie riguros compensate de cele de scoatere, din punctul de vedere al numIrului de instruc=iuni Ji al dimensiunii operanzilor. Orice eroare poate afecta mai multe date, din cauza decalaLelor. pus3 edx7 pus3 eax7 ... ;;utilizare registri pop ax ;;se recupereaza doar % octeti din valoarea anterioara a lui eax pop edx ;;nu se recupereaza edx, ci % octeti din eax, % din edx ;;decalaLul se poate propaga astfel pana la capatul stivei O altI eroare poate apIrea atunci cPnd registrul E(P este manipulat direct. -e exemplu, pentru a aloca spa=iu unei varia&ile locale (neini=ializatI), e suficient a scIdea din E(P dimensiunea varia&ilei respective. (imilar, la distrugerea varia&ilei, valoarea E(P este crescutI. Aici nu se folosesc Nn general instruc=iuni

pus3, repectiv pop, deoarece nu intereseazI valorile implicate, ci doar ocuparea Ji eli&erarea de spa=iu. (e preferI adunarea Ji scIderea direct cu registrul E(P7 evident cI o eroare Nn aceste opera=ii are consecin=e de aceeaJi naturI ca Ji cele de mai sus. Apelul func=iilor Hn apel de func=ie aratI la prima vedere ca o instruc=iune de salt, Nn sensul cI se Nntrerupe execu=ia liniarI a programului Ji se sare la o altI adresI. -iferen=a fundamentalI constI Nn faptul cI la terminarea func=iei se revine la adresa de unde sDa fIcut apelul Ji se continuI cu instruc=iunea urmItoare. -in moment ce NntrDun program se poate apela o func=ie de mai multe ori, din mai multe locuri, Ji Nntotdeauna se revine unde tre&uie, este clar cI adresa la care tre&uie revenit este memoratI Ji folositI atunci cPnd este cazul. Cum adresa de revenire este Nn mod evident o informa=ie temporarI, locul sIu este tot pe stivI. ,nstruc=iunea call Apelul unei func=ii se realizeazI prin instruc=iunea call. (intaxa: call adresa On #isual C** vom folosi nume simbolice pentru a preciza adresa, cu men=iunea cI de data asta nu este vor&a de etic3ete, ca la salturi, ci c3iar de numele func=iilor apelate. Efectul instruc=iunii call: se introduce Nn stivI adresa instruc=iunii urmItoare (adresa de revenire) Ji se face salt la adresa indicat. Aceste ac=iuni puteau fi realizate Ji cu instruc=iuni pus3 Ji Lmp, dar din nou se preferI call pentru evitarea erorilor. ,nstruc=iunea ret Fevenirea dintrDo func=ie se face prin instruc=iunea ret, care poate fi folositI fIrI operand. On acest caz, se preia adresa de revenire din vPrful stivei (similar unei instruc=iuni pop) Ji se face saltul la adresa respectivI. -in motive de conlucrare cu #isual (tudio, nu vom folosi aceastI instruc=iune. Gransmiterea parametrilor Parametrii sunt tot niJte varia&ile locale, deci se gIsesc pe stivI. Cel care face apelul are responsa&ilitatea de aDi pune pe stivI la apel Ji de aDi scoate de pe stivI le revenirea din func=ia apelatI. Avem la dispozi=ie instruc=iunea push pentru plasarea Nn stivI. Evident, aceastI opera=ie tre&uie realizatI imediat Nnainte de apelul propriuDzis. On plus, Nn lim&aLul C;C** (nu Nn toate), parametrii tre&uie puJi Nn stivI Nn ordine inversI celei Nn care se gIsesc Nn lista de parametri. Ta revenire, parametrii tre&uie scoJi din stivI, nemaifiind necesari. Cum nu ne intereseazI preluarea valorilor lor, nu se foloseJte instruc=iunea pop, care ar putea altera inutil un registru, de exemplu, ci se adunI la E(P numIrul total de octe=i ocupat de parametri (aten=ie, pe stivI se lucreazI Nn general cu . octe=i, c3iar dacI operanzii au dimensiuni mai mici).

(I luIm ca exemplu func=ia urmItoare: void s3o<6dif(int a,int &)5 int c7 c9aD&7 printf(>?d@n>,c)7 8 Apelul dif(+,S) se traduce prin secven=a care se poate vedea mai Los: void main()5 6asm5 pus3 d<ord ptr S pus3 d<ord ptr + call s3o<6dif add esp,/ 8 8 Feturnarea unei valori Conven=ia Nn #isual C** (Ji la maLoritatea compilatoarelor) este cI rezultatul se depune NntrDun anumit registru, Nn func=ie de dimensiunea sa: pentru tipurile de date de dimensiune 1 octet D Nn registrul AT pentru tipurile de date de dimensiune % octe=i D Nn registrul A' pentru tipurile de date de dimensiune . octe=i D Nn registrul EA' pentru tipurile de date de dimensiune / octe=i D Nn regiJtii E-' Ji EA' Evident, la revenirea din func=ie, cel care a fIcut apelul tre&uie sI preia rezultatul din registrul corespunzItor. #om modifica exemplul de mai sus astfel NncPt func=ia sI returneze diferen=a pe care o calculeazI NntrDo secven=I de instruc=iuni Nn lim&aL de asam&lare: 1include 2stdio.34 int compute6dif(int a,int &)5 6asm5 mov eax, a7 su& eax, &7 ;;in eax ramane rezultatul, care ;; va fi preluat la termiarea functiei 87 8 void main()5 int c7

6asm5 pus3 d<ord ptr S pus3 d<ord ptr + call compute6dif ;;se salveaza adresa de revenire pe stiva mov c, eax7 add esp,/ ;;>stergerea> parametrilor din stiva 8 printf(>-iferenta este ?d.@n>, c)7 8 Parametri Exista o alta modalitate de accesa in cadrul unei functii parametrii acesteia in cadrul unui &loc lim&aL de asam&lare. Ei se gasesc pe stiva incepand cu adresa e&p*/" si ocupa numarul de octeti al tipului de date respectiv. Exemplu, o functie cu $ parametri de tip int (o varia&ila de tip int are . octeti): void functie(int a, int &, int c)5 6asm5 mov eax, e&p*/" ;; muta in eax valoarea lui a mov e&x, e&p*1%" ;; muta in e&x valoarea lui & mov ecx, e&p*1Q" ;; muta in ecx valoarea lui c 87 8 (cris in aceasta maniera, exemplul de mai sus ar arata in felul urmator: 1include 2stdio.34 int compute6dif(int ,int )5 ;; nu mai este nevoie sa punem nume varia&ilelor, deoarece vom lucra direct cu stiva 6asm5 mov eax, e&p*/"7 su& eax, e&p*1%"7 ;;in eax ramane rezultatul, care ;; va fi preluat la termiarea functiei 87 8 void main()5 int c7 6asm5

pus3 d<ord ptr S pus3 d<ord ptr + call compute6dif ;;se salveaza adresa de revenire pe stiva mov c, eax7 add esp,/ ;;>stergerea> parametrilor din stiva 8 printf(>-iferenta este ?d.@n>, c)7 8 Asm + Pointeri. Pentru a intelege cum se folosesc ta&lourile in A(R, tre&uie inteles mai intai conceptul de pointer. PointerDul reprezinta o varia&ila ce pastreaza o adresa de memorie a unei date (>pointeaza> spre o adresa de memorie). Hn pointer poate fi utilizat pentru referirea a diferite tipuri de date (ta&louri de tip int, siruri de caracetere, matrici etc.) sau structuri de date. (c3im&and adresa memorata in pointer, pot fi manipulate informatii situate la diferite locatii de memorie. Tegatura dintre ta&louri si pointeri Eumele unui ta&lou este un pointer constant spre primul sau element. Expresiile de mai Los sunt deci ec3ivalente: nume6ta&lou Xnume6ta&lou Xnume6ta&lou !" 0nume6ta&lou nume6ta&lou !" ;; Ex.1 ,ntersc3im&area a % valori 1include 2stdio.34 void s<ap (int 0a, int 0&) 5 6asm5 mov eax, a7 ;; punem in eax adresa data de pointerul 0a mov ecx, eax"7 ;; punem in ecx valoarea efectiva a lui 0a (valoarea de la adresa pointerului) mov e&x, &7 ;; analog pt &

mov edx, e&x"7 mov eax", edx7 ;; mutam la adresa lui a valoarea lui 0& mov e&x", ecx7 ;; analog invers 8 8 void main() 5 int a9%, &9$7 s<ap(Xa,X&)7 printf(>?d ?d>, a, &)7 8 ;; Ex.% (uma elementelor dintrDun vector 1include 2stdio.34 int suma6vector (int 0, int ) 5 6asm 5 mov eax, ! ;; suma mov e&x, e&p*/" ;; primul parametru, pointer la vectorul de elemente mov ecx, ! ;; contor &ucla: cmp ecx, e&p*1%" ;; al %Dlea parametru, lungimea vectorului de elemente Lae stop add eax, e&x*ecx0." ;; elementul vectorului de pe pozitia ecx inc ecx Lmp &ucla stop: 8 8 void main() 5 int v +"95+,1,%,$,Q87 int 0p9v7

int s7 6asm5 pus3 + pus3 p call suma6vector add esp, / mov s, eax 8 printf(>(uma: ?d>, s)7 8 ;; Ex.$ Tungimea unui sir de caractere (un sir de numere se termina cu valoarea !) 1include 2stdio.34 int lungime(c3ar 0) 5 6asm5 mov eax, ! mov e&x, e&p*/" ;; adresa de inceput a sirului de caractere &ucla: cmp e&x*eax", ! ;; comparam caracterul curent cu ! Le stop inc eax Lmp &ucla stop: 8 8 void main() 5 c3ar 0sir9>zig:zag:>7 int l7 6asm5 pus3 sir call lungime add esp, . mov l, eax

8 printf(>Tungime: ?d ?d@n>, l, strlen(sir))7 8 Pentru matrice de a n" m" (n x m elemente), pentru avea acces la elementul de pe pozitia i" L" (linia i, coloana L), va tre&ui sa aflam adresa acestuia. >a i" L"> este ec3ivalent cu: >Xa * (i0m*L)0.> (adresa primului element la care adaugam i x nr6coloane * L, totul inmultit cu dimensiunea elementelor, in cazul nostru . octeti pentru int) ;; Ex. . D Construirea matricii unitate (1 pe diagonala, ! in rest) 1include 2stdio.34 void matrice6unitate(int 0, int ) 5 6asm5 mov edi, e&p*/" mov e&x, ! for6i: cmp e&x, e&p*1%" Lae exit1 mov ecx, ! for6L: cmp ecx, e&p*1%" Lae exit% mov eax, e&p*1%" mul e&x add eax, ecx ;; construim adresa de pe pozitia i" L"

;; adresa la primul element din matrice ;; dimensiunea matricii

cmp e&x, ecx Lne not6eZ mov d<ord ptr edi*eax0.", 1 ;; i 99 L, deci vom pune 1 Lmp inside not6eZ: mov d<ord ptr edi*eax0.", ! ;; altfel, ! inside:

inc ecx Lmp for6L exit%: inc e&x Lmp for6i exit1: 8 8 void main() 5 int n9+7 int mat +" +"7 int 0p 9 mat !"7 6asm 5 pus3 n pus3 p call matrice6unitate add esp, / 8 for(int i9!7 i2n7 i**) 5 for(int L9!7 L2n7 L**) printf(>?d >, mat i" L")7 printf (>@n>)7 8 8

Vous aimerez peut-être aussi