Introducere în asamblare

556 Capitolul 7. Nivel de asamblare

Traducătorii pot fi împărțiți în mod condiționat în două grupuri, în funcție de relația dintre limbile de intrare și de ieșire. Dacă limba de introducere este o reprezentare simbolică a unei limbi a mașinii numerice, traducătorul este chemat







asamblor. iar limbajul de intrare este limba de asamblare. sau doar asamblor. Dacă limbajul de introducere este un limbaj de nivel înalt (de exemplu, Java sau C), iar limbajul de ieșire este fie un limbaj numeric al mașinii, fie o reprezentare simbolică a acestuia, compilatorul este numit compilator.

Care este "limba de asamblare"?

Limbajul de asamblare este o limbă în care fiecare operator corespunde exact unei instrucțiuni de mașină. Cu alte cuvinte, într-un program scris în asamblare, există o corespondență unu-la-unu între comenzile mașinii și operatori. Dacă fiecare linie din programul de asamblare conține exact un operator și fiecare cuvânt al mașinii conține exact o comandă, atunci din programul de asamblare cu dimensiunea n liniilor, obținem programul în limbajul mașinii cu n cuvinte.

Limba de asamblare are mai multe caracteristici care o deosebesc de limbile de nivel înalt. În primul rând, aceasta este o corespondență unu-la-unu între opera-

Introducere în asamblor 557

evaluatori de limbaj de asamblare și comenzi de mașini (am menționat deja acest lucru). În al doilea rând, programatorul, scris în asamblare, este disponibil tuturor obiectelor și comenzilor mașinii țintă. Un programator care scrie în limbi de nivel înalt nu are o astfel de libertate. De exemplu, dacă mașina țintă conține un bit de preaplin, programul de asamblare îl poate testa, iar programul Java nu o face. Programul de asamblare poate executa orice comandă din setul de comandă al mașinii țintă, iar programul în limba de nivel înalt nu are. Pe scurt, tot ceea ce se poate face în limbajul mașinii poate fi făcut în asamblare, dar în același timp, programatorii care scriu programe în limbi de nivel înalt nu pot accesa multe comenzi, registre și alte obiecte. Limbile de programare a sistemului (de exemplu, C) au adesea o poziție intermediară. Deși au sintaxa inerentă limbajelor de nivel înalt, din punctul de vedere al accesibilității, mai aproape de asamblare.

În cele din urmă, programul de asamblare poate funcționa numai pe computerele din aceeași familie, iar un program scris într-un limbaj de nivel superior poate lucra teoretic pe diferite mașini. Abilitatea de a transfera software de la o mașină la alta este foarte importantă pentru multe aplicații.

Assembler Assignment

Lucrul cu limbajul de asamblare nu este ușor. Scrierea aceluiași program în asamblare durează mult mai mult decât într-un limbaj de nivel înalt. În plus, depanarea durează mult timp, iar întreținerea codului necesită mult mai mult efort.

În plus față de aceste două motive, există încă două. În primul rând, compilatorul trebuie fie să emită un program care poate fi utilizat de asamblator, fie să efectueze independent asamblarea. Astfel, cunoașterea limbajului de asamblare este esențială pentru înțelegerea modului în care compilatorul funcționează.

În cele din urmă, cineva ar trebui să scrie un compilator (și asamblorul său). În al doilea rând, asamblorul oferă o idee excelentă despre mașina reală.







nr. Pentru cei care studiază arhitectura calculatoarelor, scrierea codului de asamblare este singura modalitate de a afla ce este mașina la nivel arhitectural.

558 Capitolul 7. Nivel de asamblare

Formatul declarațiilor în asamblare

Deși structura operatorului de asamblare reflectă structura instrucțiunii mașinii corespunzătoare, limbile de asamblare pentru diferite mașini și niveluri diferite sunt similare în multe privințe, ceea ce face posibilă vorbirea despre limba asamblorului în ansamblu. Lista 7.1-7.3 arată fragmentul programului în asamblatorul x86, care calculează formula N = I + J. Operatorii sub memoria rezervă de rezervă goală pentru variabilele I. J și N. adică nu reprezintă reprezentări simbolice ale instrucțiunilor mașinii.

Listing 7.1. Calcularea expresiei N = I + J în asamblatorul x86

; și inițializați-le la 0

Pentru computerele de familie Intel (adică, x86), există mai mulți asamblori care se deosebesc una de cealaltă în sintaxă. În acest capitol, vom folosi limba asamblorului Microsoft MASM. Există, de asemenea, o mulțime de asamblori pentru procesoarele ARM, dar sunt aproape în sintaxă față de asamblatorul x86, deci un exemplu ar trebui să fie suficient.

În lista de exemple, există etichete: FORMULA, I, J și N. În asamblarea MASM, colonul este plasat numai după etichetarea comenzii, dar nu după etichetele de date. Această diferență nu este deloc fundamentală, este pur și simplu

dezvoltatorii de asamblori diferiți au gusturi diferite. Arhitectura mașinii nu afectează în niciun fel această alegere. Singurul avantaj al unui colon este acela că eticheta poate fi scrisă pe o linie separată, iar codul de operare pe următoarea linie cu aceeași indentare ca și eticheta. Fără colon, compilatorul nu a putut distinge eticheta de codul de operare atunci când a fost plasat în linii separate.

La unii asamblori, lungimea etichetei este limitată la 6 sau 8 caractere. În același timp, în majoritatea limbilor de nivel înalt, lungimea numelor este arbitrară. Numele lungi și bine alese facilitează citirea și înțelegerea programului.

Fiecare masina are mai multe registre, dar numele sunt complet diferite. Registrele Core i7 sunt numite EAX, EBX, ECX etc.

Câmpul codului de operare conține fie abrevierea simbolică a acestui cod (dacă operatorul este o reprezentare simbolică a instrucțiunii mașinii), fie o directivă pentru asamblare. Alegerea unui nume este o chestiune de gust, și prin urmare

Introducere în asamblor 559

dezvoltatorii diferiti le numesc diferit. Dezvoltatorii de asamblare MASM au decis să utilizeze denumirea MOV și să încarce registrul din memorie și să stocheze registrul în memorie. Cu acelasi succes, ei ar putea folosi MOVE asociat cu LOAD sau STORE.

Programele în limba de asamblare trebuie adesea să rezerveze spațiu pentru date. Dezvoltatorii MASM au ales numele DD (Define Double) pentru această operație, deoarece procesorul de text 8088 avea o lungime de 16 biți.

Programul de asamblare definește nu numai instrucțiunile mașinii care trebuie executate de procesor, ci și comenzile care trebuie executate de asamblatul însuși (de exemplu, alocă o mică memorie sau emite o nouă pagină de înscriere). Comenzile pentru asamblare se numesc comenzi pseudo. sau directive de asamblare. În listare 7.1, am văzut deja o pseudo-comanda tipică DD. În tabel. 7.1 afișează câteva pseudo comenzi (directive) ale asamblorului MASM pentru platforma x86.

Tabelul 7.1. Unele directive MASM Assembler

Directiva SEGMENT începe un nou segment și directiva ENDS o completează. Puteți să porniți un segment de text, apoi să porniți un segment de date, apoi să reveniți la segmentul de text și așa mai departe.

Directiva EQU dă un nume simbolic unei anumite expresii. De exemplu, după următoarea directivă, caracterul BASE poate fi folosit în program în loc de valoarea 1000:

Expresia care urmează directivei EQU. pot conține mai multe simboluri conectate prin semne de operațiuni aritmetice și de altă natură, de exemplu:

Majoritatea asamblorilor, inclusiv MASM, solicită ca simbolul să fie definit în program înainte de a apărea într-o expresie ca aceasta.

Directivele DB. DD. DW și DQ alocă memoria pentru una sau mai multe variabile de mărimi 1, 2, 4 și, respectiv, 8 octeți. De exemplu:

TABELUL DB 11, 23, 49

Directivele PROC și ENDP definesc începutul și sfârșitul procedurilor de asamblare. Procedurile în asamblare joacă același rol ca și în limbile de programare la nivel înalt. Directivele MACRO și ENDM definesc începutul și sfârșitul macrocomenzii. Vom vorbi despre macro-uri în secțiunea următoare.







Articole similare

Trimiteți-le prietenilor: