Sunteți pe pagina 1din 10

Lucrarea nr.

Setul de instruciuni al familiei de procesoare Intel x86


Scopul lucrrii
n cadrul acestei lucrri se prezint o prim parte din instruciunile limbajului de asamblare al procesoarelor Intel x86 (varianta pe 32 de biti . !estul instruciunilor vor "i prezentate #n lucrarea urmtoare. n prima parte a lucrrii se prezint sintaxa $eneral a unei instruciuni de asamblare %i c&teva re$uli de scriere a pro$ramelor. n partea practic a lucrrii se vor scrie pro$rame cu instruciunile prezentate %i se va analiza e"ectul execuiei acestora.

Prezentarea instruciunilor
'n limbaj de asamblare conine instruciuni corespunztoare unor operaii simple care sunt direct interpretate %i executate de procesor. (iecrei instruciuni din limbajul de asamblare #i corespunde #n mod strict un sin$ur cod executabil. n contrast) unei instruciuni dintr*un limbaj de nivel #nalt (ex+ ,) -ascal) etc. #i corespunde o secven de coduri (instruciuni #n cod ma%in . 'n anumit limbaj de asamblare este speci"ic pentru un anumit procesor sau eventual pentru o "amilie de procesoare. Instruciunile sunt #n direct corelaie cu structura intern a procesorului. 'n pro$ramator #n limbaj de asamblare trebuie s cunoasc aceast structur precum %i tipurile de operaii permise de structura respectiv. 'n pro$ram #n asamblare scris pentru o anumit ar.itectur de procesor nu este compatibil cu un alt tip de procesor. -entru implementarea unei aplicaii pe un alt procesor pro$ramul trebuie rescris. n sc.imb pro$ramele scrise #n limbaj de asamblare sunt #n $eneral mai e"iciente at&t #n ceea ce prive%te timpul de execuie c&t %i spaiul de memorie ocupat de pro$ram. /e asemenea) pro$ramarea #n limbaj de asamblare d o mai mare "lexibilitate %i libertate #n utilizarea resurselor unui calculator. ,u toate acestea astzi utilizarea limbajului de asamblare este mai puin "recvent deoarece e"iciena procesului de pro$ramare este mai sczut) exist puine structuri de pro$ram %i de date care s u%ureze munca pro$ramatorului) iar pro$ramatorul trebuie s cunoasc structura procesorului pentru care scrie aplicaia. n plus pro$ramele nu sunt portabile) adic nu ruleaz %i pe alte procesoare. 'n pro$ram scris #n limbaj de asamblare conine instruciuni %i directive. Instruciunile sunt traduse #n coduri executate de procesor0 ele se re$sesc #n pro$ramul executabil $enerat #n urma compilrii %i a editrii de le$turi. /irectivele sunt construcii de limbaj ajuttoare care se utilizeaz #n di"erite scopuri (ex+ declararea variabilelor) demarcarea se$mentelor %i a procedurilor) etc. %i au rol #n special #n "azele de compilare %i editare de le$turi. 1 directiv nu se traduce printr*un cod executabil %i #n consecin 2' se execut de ctre procesor.

Sintaxa unei instruciuni n limbaj de asamblare


1 instruciune ocup o linie de pro$ram %i se compune din mai multe c&mpuri) dup cum urmeaz (parantezele drepte indic "aptul c un anumit c&mp poate s lipseasc + 34etic.eta5+6 34mnemonica5 * 34parametru785 3)4parametru72566 304comentariu56

4etic.eta5 * este un nume simbolic (identi"icator dat unei locaii de memorie care conine instruciunea care urmeaz0 scopul unei etic.ete este de a indica locul #n care trebuie s se "ac un salt #n urma executrii unei instruciuni de salt0 etic.eta poate "i o combinaie de litere) ci"re %i anumite semne speciale (ex+ 7 ) cu restricia ca prima ci"r s "ie o liter

4mnemonica5 * este o combinaie de litere care simbolizeaz o anumit instruciune (ex+ add pentru adunare) mov pentru trans"er) etc. 0 denumirile de instruciuni sunt cuvinte rezervate %i nu pot "i utilizate #n alte scopuri * 4parametru785 * este primul operand al unei instruciuni %i #n acela%i timp %i destinaia rezultatului0 primul parametru poate "i un re$istru) o adres) sau o expresie care $enereaz o adres de operand0 adresa operandului se poate exprima %i printr*un nume simbolic (numele dat unei variabile * 4parametru725 * este al doilea operand al unei instruciuni0 acesta poate "i oricare din variantele prezentate la primul operand %i #n plus poate "i %i o constant * 4comentariu5 * este un text explicativ care arat inteniile pro$ramatorului %i e"ectul scontat #n urma execuiei instruciunii0 av&nd #n vedere c pro$ramele scrise #n limbaj de asamblare sunt mai $reu de interpretat se impune aproape in mod obli$atoriu utilizarea de comentarii0 textul comentariului este i$norat de compilator0 comentariul se considera p&n la s"&r%itul liniei curente ntr*o linie de pro$ram nu toate c&mpurile sunt obli$atorii+ poate s lipseasc etic.eta) parametrii) comentariul sau c.iar instruciunea. 'nele instruciuni nu necesit nici un parametru) altele au nevoie de unul sau doi parametri. n principiu primul parametru este destinaia) iar al doilea este sursa. ,onstantele numerice care apar #n pro$ram se pot exprima #n zecimal (modul implicit ) #n .exazecimal (constante terminate cu litera 9.9 sau #n binar (constante terminate cu litera 9b9 . ,onstantele al"anumerice (coduri :;,II se exprim prin litere #ntre apostro" sau text #ntre $.ilimele.

Clase de instruciuni
n aceast prezentare nu se va "ace o prezentare ex.austiva a tuturor instruciunilor cu toate detaliile lor de execuie. ;e vor prezenta acele instruciuni care se utilizeaz mai des %i au importan din punct de vedere al structurii %i al posibilitilor procesorului. -entru alte detalii se pot consulta documentaii complecte re"eritoare la setul de instruciuni I;: x86 (ex+ cursul :o: < =.e :rt o" :ssembl> Lan$ua$e) accesibil pe Internet . Instruciuni de transfer Instruciunile de trans"er realizeaz trans"erul de date #ntre re$istre) #ntre un re$istru %i o locaie de memorie sau o constant se #ncarc #ntr*un re$istru sau locaie de memorie. Transferurile de tip memorie-memorie nu sunt permise (cu excepia instruciunilor pe %iruri . La "el nu sunt permise trans"erurile directe #ntre dou re$istre se$ment. :mbii parametrii ai unui trans"er trebuie s aib aceea%i lun$ime (numr de bii . Instruciunea MOV ?ste cea mai utilizat instruciune de trans"er. ;intaxa ei este+ 34etic.eta5+6 @1A unde+ 4parametru785 B 4re$istru5C 4re$7se$ment5C4adresa7o""set5C4nume7variabil5C4expresie5 4parametru725 B 4parametru785C4constant5 4re$istru5 B ?:DC?EDC.....?;-C:DCEDC....;-C:FC:LC..../L 4expresie5 B [34re$istru7index563G4re$istru7baz563G4deplasament56] 0 aici parantezele drepte marcate cu bold sunt necesare 4parametru785) 4parametru725 304comentariu56

4re$istru7index5 B ;IC /I C?;I C ?/I 4re$istru7baz5 B EDCE- C?EDC ?E4deplasament5 B 4constant5 ?xemple+ mov ax)bx mov cl) 82. mov dx) var86 mov var32)eax mov ds) ax ?xemple de erori de sintax+ mov ax) cl mov var8) var2 mov al) 823I. mov ds) es

et8+

mov a.) 3siG8HH.6 mov al) 9:9 mov si) 823I. s"+ mov 3siGbxG3H.6) dx mov bx) cs

0 operanzi ine$ali ca lun$ime 0 ambii operanzi sunt locaii de memorie 0 dimensiunea constantei este mai mare dec&t cea a re$istrului 0 dou re$istre se$ment

Instruciunea LEA :ceste instruciuni permit #ncrcarea #ntr*un re$istru a unei adrese de variabile. -rima instruciune L?: (Jload e""ective addressJ #ncarc #n re$istrul exprimat ca prim parametru adresa liniara a variabilei din parametrul 2. L?: 4parametru785)4parametru725 ?xemple+ lea esi) var8 lea edi) 3ebxG8HH6 0 ?;I4B o""set(var8 0 ?/I4B ?EDG8HH

Instruciunea L?: este ec.ivalenta (are acela%i e"ect cu urmtoarea instruciune+ @1A 4re$istru5) offset 4memorie5 Instruciunea XCH :ceast instruciune sc.imb #ntre ele coninutul celor doi operanzi. D,FK 4parametru785) 4parametru725 :tenie+ parametrul 2 nu poate "i o constant. ?xemple+ xc.$ al) b. xc.$ ax)bx Instruciunile !"#H $i !O! ,ele dou instruciuni opereaz #n mod implicit cu v&r"ul stivei. Instruciunea -';F pune un operand pe stiv) iar -1- extra$e o valoare de pe stiv %i o depune #ntr*un operand. n ambele cazuri re$istrul indicator de stiv (?;- se modi"ic corespunztor (prin decrementare %i respectiv incrementare ast"el #nc&t re$istrul ?;- s indice poziia curent a v&r"ului de stiv. ;intaxa instruciunilor este+ -';F 4parametru785

-1- 4parametru785 1perandul trebuie sa "ie o valoare pe 86 sau 32 bii) dar este recomandat sa se foloseasc% doar &alori pe '( de )ii. :ceste instruciuni sunt utile pentru salvarea temporar %i re"acerea coninutului unor re$istre. :ceste operaii sunt necesare mai ales la apelul de rutine %i la revenirea din rutine. n cazul introducerii #n stiv) prima operaie care se realizeaz este decrementarea indicatorului de stiv ?;- cu 2 (la introducerea unei valori pe 86 bii sau I (la introducerea unei valori pe 32 bii ) urmat de memorarea operandului con"orm acestui indicator. n cazul extra$erii din stiv prima operaie care se realizeaz este citirea operandului con"orm indicatorului de stiv urmat de incrementarea cu 2 sau I a indicatorului. ?xemple+ pus. eax pop bx pus. var86 pop var32

Instruciuni de transfer pentru indicatorii de condiie


n setul de instruciuni al microprocesorului I8H86 exist instruciuni pentru #ncrcarea si memorarea indicatorilor de condiie. ;intaxa este urmtoarea+ L:F( ;:F( -';F( -1-( 1ctetul mai puin semni"icativ al re$istrului indicatorilor de condiie poate "i #ncrcat #n re$istrul a. "olosind instruciunea L:F() respectiv poate "i #nscris cu coninutul re$istrului a. "olosind instruciunea ;:F(. ;tructura octetului care se trans"er este urmtoarea + bitul L ;( 6 N( M O I :( 3 O 2 -( 8 O H ,(

/ac se dore%te salvarea sau re"acerea #ntre$ului re$istru al indicatorilor de condiie se "olosesc instruciunile -';F( %i -1-(. ;tructura cuv&ntului care se trans"er #n acest caz este urmtoarea+ Eitul 8M 8I 83 82 88 8H P 8 L 6 .. 1( /( I( =( ;( N( M .. I :( 3 .. 2 -( 8 .. H ,(

Instruciuni aritmetice :ceste instruciuni e"ectueaz cele patru operaii aritmetice de baz+ adunare) scdere) #nmulire %i #mprire. !ezultatul acestor instruciuni a"ecteaz starea indicatorilor de condiie. Instruciunile A** $i A*C :ceste instruciuni e"ectueaz operaia de adunare a doi operanzi) rezultatul plas&ndu* se #n primul operand. : doua instruciune :/, (:// Qit. carr> #n plus adun %i coninutul indicatorului de transport ,(. :ceast instruciune este util pentru implementarea unor adunri #n care operanzii sunt mai lun$i de 32 de bii.

:// 4parametru785)4parametru725 :/, 4parametru785)4parametru725 ?xemple+ add ax) 823I. add bx) ax adc dx) var86 Instruciunile #"+ $i #++ :ceste instruciuni implementeaz operaia de scdere. : doua instruciune) ;EE (;ubtract Qit. borroQ scade %i coninutul indicatorului ,() "olosit #n acest caz pe post de bit de #mprumut. ,a %i :/,) ;EE se "olose%te pentru operanzi de lun$ime mai mare. ;'E 4parametru785)4parametru725 ;EE 4parametru785)4parametru725 Instruciunile M"L $i IM"L :ceste instruciuni e"ectueaz operaia de #nmulire) @'L pentru #ntre$i "r semn %i I@'L pentru #ntre$i cu semn. /e remarcat c la operaiile de #nmulire %i #mprire trebuie s se tin cont de "orma de reprezentare a numerelor (cu semn sau "r semn ) pe c&nd la adunare %i scdere acest lucru nu este necesar. -entru a evita dese dep%iri de capacitate s*a decis ca rezultatul operaiei de #nmulire s se pstreze pe o lun$ime dubl "a de lun$imea operanzilor. :st"el dac operanzii sunt pe octet rezultatul este pe cuv&nt) iar daca operanzi sunt pe cuv&nt rezultatul este pe dublu*cuv&nt. /e asemenea se impune ca primul operand %i implicit %i rezultatul s se pstreze #n re$istrul acumulator. /e aceea primul operand nu se mai speci"ic. @'L 4operand 85 I@'L 4operand 85 I@'L 4operand 85) 4operand 25 I@'L 4operand 85) 4operand 25) 4valoare imediata5 ?xemple+ mul d. mul bx imul var8 0 :D4B:LR/F 0 /D+:D4B :DRED 0 :D4B:LRvar8

/D este extensia re$istrului acumulator :D

Instruciunea @'L are un sin$ur operand explicit) ceilali "iind implicii. In "uncie de dimensiunea operandului explicit) #nmulirea are loc ast"el+ @'L 4operand78biti5 Rezultat nmulire+ :DB:LR4operand78biti5 @'L 4operand786biti5 Rezultat nmulire+ /D+:DB:DR4operand786biti5 @'L 4operand732biti5 Rezultat nmulire+ ?/D+?:DB?:DR4operand732biti5 :celea%i re$uli se aplica si la instruciunea I@'L cu 8 operand. La instruciunea I@'L cu 2 operanzi) rezultatul #nmulirii celor 2 operanzi este pstrat in primul operand. In

cazul utilizrii instruciunii I@'L cu 3 operanzi) primul operand pstreaz rezultatul #nmulirii intre al doilea operand si valoarea imediat. Instruciunile *IV $i I*IV :ceste instruciuni e"ectueaz operaia de #mprire pe #ntre$i "r sem %i respectiv cu semn. -entru a cre%te plaja de operare se consider c primul operand) care #n mod obli$atoriu trebuie s "ie #n acumulator) are o lun$ime dubl "a de al doilea operand. -rimul operand nu se speci"ic. /IA 4operand5 I/IA 4operand5 ?xemple+ div div cl bx 0 :L4B:DS,L %i :F4B:D mod ,L (adic restul #mpririi 0 :D4B (/D+:D SED %i /D4B(/D+:D mod ED

Instruciunile /IA si I/IA au un sin$ur operand explicit) ceilali "iind implicii. In "uncie de dimensiunea operandului explicit) #mprirea are loc ast"el+ /IA 4operand78biti5 Rezultat mprire+ :LB:DS4operand78biti50 :FB:D mod 4operand78biti5 /IA 4operand786biti5 Rezultat mprire+ :DB/D+:DS4operand786biti50 /DB/D+:D 4operand786biti5 /IA 4operand732biti5 Rezultat mprire+ ?:DB?/D+?:DS4operand732biti50 ?/DB?:D 4operand732biti5

mod mod

Instruciunile I,C $i *EC :ceste instruciuni realizeaz incrementarea %i respectiv decrementarea cu o unitate a operandului. :ceste instruciuni sunt e"iciente ca lun$ime %i ca vitez. ?le se "olosesc pentru contorizare %i pentru parcur$erea unor %iruri prin incrementarea sau decrementarea adreselor. I2, 4parametru5 /?, 4parametru5 ?xemple+ inc si dec cx 0 ;I4B;IG8 0 ,D4B,D*8

Instruciunea CM! :ceast instruciune compar cei doi operanzi prin scderea lor. !ezultatul scderii nu se memoreaz. Instruciunea are e"ect numai asupra urmtorilor indicatori de condiie+ N() ;() 1() ,(. Aalorile indicatorilor de condiie pot "i apoi interpretate in mod di"erit daca valorile comparate au "ost cu semn sau "r semn. :ceast instruciune precede de obicei o instruciune de salt condiionat. printr*o combinaie de instruciune de comparare %i o instruciune de salt se pot veri"ica relaii de e$alitate) mai mare) mai mic) mai mare sau e$al) etc. ,@- 4parametru785) 4parametru725

?xemplu+ cmp ax) MH. Instruciuni logice :ceste instruciuni implementeaz operaiile de baz ale lo$icii booleene. 1peraiile lo$ice se e"ectueaz la nivel de bit) adic se combin printr*o operaie lo$ic "iecare bit al operandului 8 cu bitul corespunztor din operandul al doilea. !ezultatul se $enereaz #n primul operand. Instruciunile A,*- O.- ,OT $i XO. :ceste instruciuni implementeaz cele patru operaii de baz+ TI) ;:') 2e$aie %i ;:'*?xclusiv. :2/ 4parametru785)4parametru725 1! 4parametru785) 4parametru725 21= 4parametru785 D1! 4parametru785)4parametru725 ?xemple+ and or and xor al) H". bx) HHHH8888HHHH8888b al)c. eax)eax 0 %ter$e coninutul lui eax

Instruciunea TE#T :ceast instruciune e"ectueaz operaia TI lo$ic "r a memora rezultatul. ;copul operaiei este de a modi"ica indicatorii de condiie. Instruciunea evit distru$erea coninutului primului operand. =?;= 4parametru785)4parametru725 ?xemple+ test al) HHH8HHHHb test bl) H". 0 se veri"ic dac bitul /I din al este zero sau nu 0se veri"ica dac prima ci"r .exazecimal din bl este H

Instruciuni de deplasare i de rotire


Instruciunile #HL- /#AL0- #H. $i #A. :ceste instruciuni realizeaz deplasarea (en$. s.i"t la st&n$a %i respectiv la dreapta a coninutului unui operand. La deplasarea Jlo$icJ (;FL) ;F! biii se copiaz #n locaiile #nvecinate (la st&n$a sau la dreapta ) iar pe locurile rmase libere se #nscrie H lo$ic. La deplasarea JaritmeticJ (;:L) ;:! se consider c operandul conine un numr cu semn) iar prin deplasare la st&n$a %i la dreapta se obine o multiplicare %i respectiv o divizare cu puteri ale lui doi (ex+ o deplasare la st&n$a cu 2 poziii binare este ec.ivalent cu o #nmulire cu I . La deplasarea la dreapta se dore%te meninerea semnului operandului) de aceea bitul mai semni"icativ (semnul se menine %i dup deplasare. La deplasarea la st&n$a acest lucru nu este necesar) de aceea instruciunile ;FL %i ;:L reprezint aceea%i instruciune. n "i$ura de mai jos s*a reprezentat o deplasare lo$ic %i o deplasare aritmetic la dreapta. ;e observ c bitul care iese din operand este #nscris #n indicatorul de transport ,(

/L /L

/6 /6

.... ....

/8 /8

/H /H

,( ,(

;F! ;:!

(ormatul instruciunilor+ ;FL ;:L ;F! ;:L 4parametru785) 4parametru725 4parametru785) 4parametru725 4parametru785) 4parametru725 4parametru785) 4parametru725

-rimul parametru este #n concordan cu de"iniiile anterioare0 al doilea parametru speci"ic numrul de poziii binare cu care se "ace deplasare0 acest parametru poate "i 8 sau dac numrul de pa%i este mai mare atunci se indica prin re$istrul ,L. Incepand cu procesorul 8H386 se accept %i "orma #n care constanta este di"erit de 8. ?xemple+ s.l eax) 8 sar ebx) 3 s.r var) cl Instruciunile de rotire .O.- .OL- .C.- .CL :ceste instruciuni realizeaz rotirea la dreapta sau la st&n$a a operandului) cu un numr de poziii binare. /i"erena "a de instruciunile anterioare de deplasare const #n "aptul c #n poziia eliberat prin deplasare se introduce bitul care iese din operand. !otirea se poate "ace cu implicarea indicatorului de transport (,( #n procesul de rotaie (!,!) !,L sau "r (!1!) !1L . n ambele cazuri bitul care iese din operand se re$se%te #n indicatorul de transport ,(. (i$ura de mai jos indic cele dou moduri de rotaie pentru o rotaie la dreapta. /L /L (ormatul instruciunilor+ !1! !1L !,! !,L 4parametru785) 4parametru725 4parametru785) 4parametru725 4parametru785) 4parametru725 4parametru785) 4parametru725 /6 /6 .... .... /8 /8 /H /H ,( ,( !1! !,!

!e"eritor la parametri) se aplic acelea%i observaii ca %i la instruciunile de deplasare.

Instruciuni de intrare/ieire
:ceste instruciuni se utilizeaz pentru e"ectuarea trans"erurilor cu re$istrele (porturile inter"eelor de intrareSie%ire. =rebuie remarcat "aptul c la procesoarele Intel acestea sunt sin$urele instruciuni care opereaz cu porturi. Instruciunile I, $i O"T Instruciunea I2 se "olose%te pentru citirea unui port de intrare) iar instruciunea 1'= pentru scrierea unui port de ie%ire. ;intaxa instruciunilor este+ I2 4acumulator5) 4adres7port5 1'= 4adres7port5) 4acumulator5 unde+ 4acumulator5 * re$istrul ?:DS:DS:L pentru trans"er pe 32S86S8 biti 4adresa7port5 * o adres exprimabil pe 8 bii sau re$istrul /D ;e observ c dac adresa portului este mai mare dec&t 2MM atunci adresa portului se transmite prin re$istrul /D. ?xemple+ in al) 2H. mov dx) adresa7port out dx) ax

Instruciuni speciale
n aceast cate$orie s*au inclus acele instruciuni care au e"ect asupra modului de "uncionare al procesorului. Instruciunile CLC- #TC- CMC :ceste instruciuni modi"ic starea indicatorului ,( de transport. :ceste instruciuni au urmtoarele e"ecte+ ,L, %ter$e (en$. clear indicatorul) ,(BH ;=, seteaz indicatorul) ,(B8 ,@, inverseaz starea indicatorului) ,(B21= ,( Instruciunile CLI $i #TI :ceste instruciuni %ter$ %i respectiv seteaz indicatorul de #ntrerupere I(. n starea setat (I(B8 procesorul detecteaz #ntreruperile mascabile) iar #n starea invers bloc.eaz toate #ntreruperile mascabile. Instruciunile CL* $i #T* :ceste instruciuni modi"ica starea indicatorului de direcie /(. -rin acest indicator se controleaz modul de parcur$ere a %irurilor la operaiile pe %iruri+ prin incrementare (/(BH sau prin decrementare (/(B8 . Instruciunea C!"I* :ceast instruciune permite identi"icarea tipului de procesor pe care rupeaza pro$ramul.

Mersul lucrrii
8. /iscuii le$ate de problemele #nt&mpinate in #nele$erea documentaiei scrise. 2. -roblema rezolvata in s3ex8.asm ;a se implementeze in limbaj de asamblare expresia de mai jos "olosind instruciuni de deplasare+ ?:D B LR?:D<2R?ED<?EDS8 a. ;e va compila s3ex8.asm b. ;e va executa in 1ll>db$ c. ;e vor urmri sc.imbrile care au loc la nivelul re$i%trilor si a "la$urilor 3. ;a se implementeze in limbaj de asamblare expresia de la punctul 2 "olosind instruciuni aritmetice. I. -roblema rezolvata in s3ex2.asm ;a se scrie un pro$ram in limbaj de asamblare care $enereaz un #ntre$ reprezentabil pe octet si #l pune in locaia de memorie !?N dup "ormula+ !?N B :LR2'@8G(2'@2R:LGEL !?N) 2'@8 si 2'@2 sunt valori reprezentate pe octet a"late in memorie. a. ;e va compila s3ex2.asm b. ;e va executa in 1ll>db$ c. ;e vor urmri sc.imbrile care au loc la nivelul re$i%trilor) memoriei si a "la$urilor M. ;a se scrie un pro$ram in limbaj de asamblare care calculeaz un #ntre$ reprezentabil pe cuv&nt si #l pune in locaia de memorie !?N dup "ormula+ !?N B :DR2'@8G(2'@2R:DGED !?N) 2'@8 si 2'@2 sunt valori reprezentate pe cuv&nt a"late in memorie. a. ;e va compila pro$ramul scris. b. ;e va executa in 1ll>db$ c. ;e vor urmri sc.imbrile care au loc la nivelul re$i%trilor) memoriei si a "la$urilor

S-ar putea să vă placă și