- Limbajul de asamblare își organizează instrucțiunile în funcție de scop: transfer, calcul, control al fluxului și multe altele.
- Fiecare instrucțiune constă dintr-un opcode și operanzi, cu formate diferite în funcție de arhitectură.
- Există mai multe moduri de adresare pentru accesarea datelor, cum ar fi imediată, directă și indirectă.
Limbajul de asamblare a fost unul dintre pilonii fundamentali ai dezvoltării de software încă de la începuturile informaticii. Deși limbajele de nivel înalt domină scena astăzi, asamblatorul rămâne utilizat pe scară largă și relevant în mediile în care controlul hardware, optimizarea sau constrângerile de resurse sunt o prioritate.
În acest articol, vom analiza în detaliu tipurile de instrucțiuni în limbaj de asamblare, analizând structura, scopul, modurile de adresare și modul în care sunt organizate în diferite arhitecturi. Veți găsi, de asemenea, exemple, formate și o prezentare generală cuprinzătoare care vă va permite să înțelegeți pe deplin logica din spatele acestor instrucțiuni, care funcționează în strânsă legătură cu hardware-ul.
Ce este o instrucțiune în limbaj de asamblare?
O instrucțiune de asamblare este o comandă pe care procesorul o poate înțelege direct (odată tradusă în cod mașină de către un program de asamblare). Fiecare instrucțiune are un scop specific și este de obicei compusă dintr-un mnemonic care reprezintă operația și unul sau mai mulți operanzi care indică de unde sunt preluate datele și/sau unde sunt stocate rezultatele.
Aceste instrucțiuni depind în mare măsură de arhitectura procesorului, astfel încât fiecare tip de procesor (fie că este x86, ARM, MIPS, printre altele) are propriul set de instrucțiuni cu o sintaxă și capabilități specifice.
Structura unei instrucțiuni
Instrucțiunile sunt de obicei compuse din două părți:
- Codul operațiunii (opcode): Indică acțiunea care trebuie executată, cum ar fi adăugarea, mutarea datelor, compararea etc.
Operanzii furnizează informațiile necesare pentru efectuarea operației și pot fi stocați în registre, memorie sau pot fi constante. Nu toate instrucțiunile necesită operanzi, iar în unele cazuri, aceștia pot fi impliciti în instrucțiune sau stocați în registre predefinite.
Tipuri de instrucțiuni în limbajul de asamblare
În funcție de funcționalitatea pe care o îndeplinesc în cadrul unui program, instrucțiunile în limbaj de asamblare pot fi clasificate în mai multe grupuri. Cele mai relevante sunt detaliate mai jos:
1. Instrucțiuni de transfer de date
Aceste instrucțiuni permit copierea datelor dintr-o locație în alta fără a modifica conținutul acestora la sursă. Sunt esențiale pentru mutarea informațiilor între registre, memorie și periferice.
Unele dintre cele mai comune instrucțiuni din acest grup sunt:
- MOV: Copiază conținutul unui operand în altul. De exemplu,
MOV AX, BXCopiați conținutul fișierului BX în AX. - MOVS / MOVSB / MOVSW: Mută șiruri de caractere de la o adresă sursă (SI) la o adresă destinație (DI), automatizând procesul de transfer.
- LODS / LODSB / LODSW: Încarcă o valoare de la adresa indicată de registrul SI în acumulator (AL sau AX).
- CITIRE: Încarcă o adresă efectivă în loc de valoare. Util pentru obținerea adresei unei variabile sau structuri.
2. Instrucțiuni privind bateria
Stiva este o structură LIFO (ultimul intrat, primul ieșit) utilizată pentru stocarea temporară a datelor, transmiterea parametrilor sau salvarea contextului de execuție.
- APĂSAȚI: Stochează o valoare în stivă, decrementând pointerul SP.
- POP: Preia cea mai recentă valoare stocată în stivă, incrementând SP.
- PUSHF / POPF: Acestea stochează și preiau starea flag-urilor CPU din stivă.
3. Instrucțiuni aritmetice și logice
Acestea permit efectuarea de calcule și operații pe biți. Aceste instrucțiuni sunt esențiale pentru manipularea datelor numerice și luarea deciziilor în fluxul programului.
Printre cele mai utilizate găsim:
- ADĂUGAȚI / SUBTOTALIZAȚI: Adunare și scădere.
- MUL / IMUL: Înmulțiri binare.
- DIV / IDIV: Împărțire (întreag sau cu semn).
- ȘI / SAU / XOR / NU: Operații logice pe bit.
- SHL / SHR / ROL / ROR: Deplasări și rotații de biți.
4. Instrucțiuni de control al fluxului
Acestea permit modificarea secvenței de execuție a programului , introducând salturi sau apeluri condiționate și necondiționate către alte instrucțiuni.
- JMP: Sare necondiționat la o altă adresă din program.
- APEL / RETURNARE: Apelează o subrutină și returnează o valoare.
- JE/JNE/JG/JL/JZ/JNZ: Salturi condiționate, acestea sunt executate dacă sunt îndeplinite anumite condiții (după o comparație).
5. Instrucțiuni de intrare/ieșire (I/O)
Acestea permit comunicarea dintre procesor și dispozitivele externe. Aceste instrucțiuni permit citirea și scrierea datelor către/dinspre porturi (hardware).
- ÎN: Citește date de la un port de intrare.
- OUT: Trimite date către un port de ieșire.
6. Instrucțiuni în virgulă mobilă
Multe procesoare au coprocesoare matematice (sau instrucțiuni speciale) dedicate lucrului cu numere zecimale (în virgulă mobilă). Aceste instrucțiuni permit operațiuni precum:
- Adunarea, scăderea, înmulțirea și împărțirea numerelor reale.
- Operații trigonometrice (sinus, cosinus, tangentă).
- Operații logaritmice, exponențiale și cu rădăcini.
Aceste instrucțiuni respectă de obicei standardul IEEE 754 pentru precizie numerică.
Moduri de adresare
O parte fundamentală a proiectării instrucțiunilor este modul în care este identificată locația operanzilor. Modurile de adresare definesc modul în care procesorul accesează datele.
1. Adresare imediată
Datele sunt incluse direct în instrucțiune. Este rapid, dar nu permite modificarea valorilor fără a schimba instrucțiunea.
MOV AX, 5
2. Adresare directă
Adresa de memorie care conține datele este specificată explicit.
MOV AX,
3. Adresare indirectă
Adresa efectivă se obține din conținutul unei înregistrări. Foarte flexibilă și utilizată pentru structuri și liste înlănțuite.
MOV AX,
4. Adresare indexată
Adresa se calculează prin adăugarea unei baze și a unui index (de exemplu, pentru a parcurge tablouri). Se utilizează registre speciale, cum ar fi SI, DI sau registre bază + offset.
MOV AX,
Formate de instrucțiuni: diferite tipuri în funcție de arhitectură
Structura unei instrucțiuni poate varia în funcție de arhitectură. Formatele comune includ:
Format cu 4 căi
Include doi operanzi, o locație pentru rezultat și adresa următoarei instrucțiuni. Acum este învechită din cauza complexității sale.
Format cu 3 căi
Specifică doi operanzi și o adresă de destinație. Este comun în arhitecturile RISC moderne.
Format cu 2 căi
Folosește un operand sursă și un operand destinație (destinația poate contribui și ea cu valoare). Popular pe arhitecturile x86 și alte arhitecturi CISC.
Format unidirecțional
Se specifică un singur operand; celălalt se presupune a fi acumulatorul. Obișnuit în procesoarele mai vechi și în sistemele simple.
Format de adresă 0 (bazat pe stivă)
Operațiile folosesc stiva pentru a prelua și stoca operanzi și rezultate. Foarte eficient pentru mașinile bazate pe stivă, cum ar fi unele calculatoare programabile.
Instrucțiuni macro și pseudo-coduri de operare
Pentru a îmbunătăți productivitatea, multe programe de asamblare oferă macro-instrucțiuni , care extind o singură linie în mai multe instrucțiuni propriu-zise. Acestea sunt utile pentru a evita repetarea modelelor complexe sau pentru a crea structuri de nivel înalt, cum ar fi bucle sau instrucțiuni condiționale.
L pseudo-coduri de operare Acestea sunt instrucțiuni pe care asamblatorul le traduce intern într-o secvență reală de instrucțiuni. De exemplu, NOP (fără operație) poate fi tradus ca XCHG AX, AX pe procesorul x86.
Directivele de asamblare
Directivele ( numite și pseudo-operații ) nu sunt instrucțiuni în sens strict. Ele servesc la controlul procesului de asamblare, la definirea datelor, a secțiunilor de cod, a macrocomenzilor, a condițiilor de compilare etc.
Exemplele comune includ:
- .date / .code: Acestea indică secțiunea de date sau de cod.
- .org: Setează adresa de la care va începe asamblarea.
- .ech: Definește constante simbolice.
Cazuri de utilizare a limbajului de asamblare
În ciuda creșterii numărului de limbaje de nivel înalt, limbajul de asamblare rămâne esențial în mai multe domenii:
- Dezvoltarea de sisteme integrate și microcontrolere.
- Programarea driverelor, bootloader-elor și BIOS-ului.
- Optimizare extremă în aplicații precum jocuri video sau criptografie.
- Inginerie inversă, depanare și hacking de nivel scăzut.
În plus, instruirea în limbajul de asamblare ocupă încă un loc important în studiile de informatică și electronică, deoarece oferă o înțelegere profundă a modului în care funcționează un procesor, a modului în care datele sunt stocate și manipulate și a modului în care instrucțiunile sunt executate la nivel binar.
Înțelegerea tuturor tipurilor de instrucțiuni de asamblare, a structurii, funcționalității și modurilor de adresare ale acestora oferă o bază solidă pentru orice programator care dorește să aprofundeze programarea de nivel scăzut sau să înțeleagă modul în care limbajele de nivel înalt sunt în cele din urmă traduse în cod mașină. Deși utilizarea sa a devenit mai specifică, rămâne un instrument esențial în multiple domenii critice ale dezvoltării de software și sisteme.