Cerintele minime sunt cateva cunostinte de limbaj C... nu ceva foarte complicat, doar ce este un pointer, operatiunea de dereferentiere si operatorii ++ si +=... si muuuuuulta rabdare pentru ca nu e un subiect usor de inteles (nici de explicat, mi-am dat seama astazi
)Ceea ce urmeaza e o scurta introducere in limbajele de asamblare. Va fi structurata cam asa:
1. Ce sunt limbajele de asamblare
2. Exemple
3. Avantaje / dezavantaje
Cam asta va contine prezentarea, daca aveti deja habar nu are sens sa mai parcurgeti... nu va fi nimic prea special, eventual ceva exemple mai "exotice" zic eu... Here we go...
Limbajele de asamblare, dupa cum precizeaza descrierea topicului, sunt limbaje tipice pentru microprocesoare, microcontrollere si alte tipuri de circuite.
Pentru a explica mai bine, sa luam exemplul unui microprocesor. Il vom considera la inceput ca un simplu dispozitiv de tip intrare-iesire. La "intrare" vom pune niste date pe care acesta le va prelucra si va oferi rezultatele la "iesire". Exemplul acesta presupune un program fix - microprocesorul va executa intotdeauna acelasi program, ceea ce stim ca nu este cazul in realitate. De aceea, va trebui sa ii specificam si cum vrem sa fie procesate datele. Astfel introducem ideea de "comenzi" care trebuie transmise procesorului. Cum comenzile se transmit sub forma binara, un programator ar trebui sa scrie un program sub forma: 000101101011 - ceea ce nu ar fi tocmai prietenos. Pentru a rezolva aceasta problema s-au inventat limbajele de asamblare - limbaje care prezinta o interfata mai accesibila programatorilor.
Instructiunile in aceste limbaje sunt foarte simple (din punct de vedere al operatiunilor executate) si scurte (mai sunt numite si "mnemonice" pentru ca ajuta la memorarea operatiilor). De exemplu, sa spunem ca pentru a aduna doua valori procesorul va primi instructiunea 101 (in format binar); in limbaj de asamblare se poate atribui o instructiune de tipul ADD 4, 5 pentru insumarea celor doua numere - aceasta instructiune va fi apoi transformata in cod binar si transmisa procesorului sub forma 101 0100 0101 (am codificat valorile pe cate 4 biti); se observa clar avantajul folosirii unui astfel de limbaj intermediar.
Pentru a exemplifica mai bine, sa vedem cateva exemple de cod scris in diferite limbaje de asamblare:
- portiune dintr-un cod C
(*a)++;
(*a) *= 2.5;
- traducerea codului C in limbaj de asamblare pentru x86 (doar partea de calcul am inclus-o)
movl 4(%esp), %eax #citeste a de pe stiva (a era un parametru de tip int *)
movl (%eax), %ecx #muta in registrul ECX (o zona de memorie accesibila direct de procesor)
#valoarea de la adresa din EAX - practic echivalentul lui *a
incl %ecx #incrementeaza valoarea din ECX
cvtsi2ss %ecx, %xmm0 #se face o conversie, mai mult de explicat pentru registrii xmm, sarim peste
#la final *a va fi in registrul XMM0
mulss LCPI1_0, %xmm0 #LCPI1_0 e o valoare definita in alta parte a programului (era prea lung
#ca sa includ tot; practic tine valoarea 2.5); se face inmultirea (MULtiply)
cvttss2si %xmm0, %ecx #se muta rezultatul inapoi in ECX
movl %ecx, (%eax) #se pune rezultatul la adresa de memorie indicata de pointerul a
ret #iese din functie
Stiu ca e destul de greu de inteles dar am incercat sa explic cat mai bine...
- traducerea codului in limbaj de asamblare pentru un ATI Radeon 4890 (din nou, doar partea de calcul):
02 ALU: ADDR(34) CNT(5)
2 w: ADD_INT ____, R0.x, 1
3 t: I_TO_F ____, PV2.w
4 y: MUL_e ____, PS3, (0x40200000, 2.5f).x
5 t: F_TO_I R0.x, PV4.y
03 MEM_EXPORT_WRITE_IND: DWORD_PTR[0+R1.x].x___, R0, ELEM_SIZE(3)
In linii mari seamana cu ce s-a intamplat mai inainte, valoarea e stocata in registrul R0.x, se incrementeaza, transforma si apoi inmulteste... la sfarsit se rescrie in memorie...
- nu am cod c la indemana actualmente, dar asta e un exemplu de o bucla dintr-un program scris in asamblare pentru un ADSP Blackfin, un procesor specializat pentru prelucrari de semnale / imagini:
lsetup(strt, end) lc0 = p4 >> 1;
mnop || r0 = [i0++] || r1 = [i3++];
strt: a1 = r0.h * r1.l, a0 = r0.l * r1.l (is) || r0.l = w[i0++] || r2 = [i3++];
a1 += r0.l * r1.h, a0 += r0.h * r1.h (is) || r0.h = w[i0--];
a1 += r0.h * r2.l, a0 += r0.l * r2.l (is) || r0 = [i1++] || r3 = [i3++];
a1 += r0.h * r2.h, a0 += r0.l * r2.h (is) || r0.l = w[i1++];
a1 += r0.l * r3.l, a0 += r0.h * r3.l (is) || r0.h = w[i1--] || r1 = [i3++];
a1 += r0.h * r3.h, a0 += r0.l * r3.h (is) || r0 = [i2++];
a1 += r0.h * r1.l, a0 += r0.l * r1.l (is) || r0.l = w[i2++] || r2 = [i3++];
a1 += r0.l * r1.h, a0 += r0.h * r1.h (is) || r0.h = w[i2--] || r1 = [i3++];
r6.h = (a1 += r0.h * r2.l), r6.l = (a0 += r0.l * r2.l) (is);
end: mnop || [p1++] = r6 || r0 = [i0++];
Comentarii:
lsetup = loop setup, initializeaza o bucla; a1, r0, i0, ... sunt o parte din registrii procesorului...
Din exemplele de mai sus putem sa tragem cateva concluzii: limbajele de asamblare au cateva elemente comune, cel putin la nivel teoretic: fiecare foloseste registri - niste regiuni de memorie proprie unde se pot stoca variabile; registrii sunt foarte rapizi dar si putin la numar. De asemenea, in fiecare exista o serie de formate de reprezentare a datelor - datele de tip intreg se stocheaza binar intr-un fel, floaturile altfel, de unde si nevoia de instructiuni de conversie intre formate - cvttss2si si mai sugestivele I_TO_F si F_TO_I. Mai e nevoie si de modalitati de a accesa locatii din memoria ram, de obicei prin incadrarea adresei (sau registrului care contine adresa) intre paranteze. Cam aceste concepte apar in TOATE limbajele de asamblare si sunt elementele care fac posibila intelegerea unui limbaj complet nou - pe baza acestor asemanari.
Din cate s-a vazut in exemple, programele scrise in limbaj de asamblare sunt destul de dificile si de greu de inteles. Se spune ca in ziua de astazi limbajele de asamblare sunt scrise pentru compilatoare. De ce sa se mai foloseasca totusi atunci pentru altceva decat pentru compilarea codului C in cod-masina pentru procesor? Acum vom mentiona prima data dezavantajele, apoi avantajele:
Dezavantaje:
1) Portabilitate - cea mai mare problema; codul C poate fi recompilat dar limbajul de asamblare foloseste arhitectura specifica a unui procesor - prin urmare, nu exista posibilitatea asta...
2) Dificultate - e destul de greu de programat in asamblare, ca sa nu mai vorbim de programat corect

3) Curba de invatare - nu e grea numai programarea ci si invatarea limbajului in sine
Cu toate acestea, folosirea lor prezinta si destule avantaje:
1) Performanta - sunt limbajele care folosesc la maxim resursele folosite de un anumit echipament pentru ca toate instructiunile sunt facute DOAR pentru acea arhitectura. De exemplu, un procesor are ca dimensiune standard a blocului de procesare 128 de biti - va fi clar dezavantajat de operatiuni continue pe 32 de biti (un int din c - presupunem ca nu avem un compilator care sa reuseasca sa optimizeze codul sa foloseasca facilitatea aceasta)
2) Dimensiunea codului - mult mai redusa decat pentru codurile compilate care contin si informatii suplimentare
3) "Iluminarea", ca sa zic asa - eu cel putin am simtit ca inteleg in sfarsit complet cum functioneaza un calculator... ca sa il citez pe Paul Graham - "Lisp is worth learning for the profound enlightenment experience you will have when you finally get it; that experience will make you a better programmer for the rest of your days, even if you never actually use Lisp itself a lot. " - cred ca se poate spune asta si despre asamblare... n-o s-o folositi enorm dar daca veti lucra in limbaje low-level va va ajuta mult
Cele doua avantaje pot sa para destul de putin, dar pentru anumite categorii de echipamente (sa ne gandim la microcontrollere, la procesoare de semnal si altele - care sunt mult mai mici si mai putin performante decat un procesor normal dintr-un PC dar mai ieftine si mai eficiente energetic) sunt niste avantaje foarte importante. Se poate ca printr-o astfel de optimizare un program sa incapa intr-un microcontroller dar prin compilarea din C sa nu fie posibil acest lucru...
Ma opresc aici... am scris deja destul de mult (am vreo ora de cand lucrez la asta
) si cred ca multi care vor incepe se vor plictisi pe parcurs... sper ca am explicat destul de bine pentru cine vrea sa afle cam ce sunt limbajele de asamblare... astept intrebari dupa curs

