limbaj de asamblare | |
---|---|
Clasa de limba | imperativ |
Tipul de execuție | asamblabile |
Aparut in | 1949 |
Extensie de fișier | .asmsau [1].s |
Fișiere media la Wikimedia Commons |
Limbajul de asamblare ( limba engleză de asamblare ) - reprezentarea comenzilor procesorului într-o formă care poate fi citită de om. Limbajul de asamblare este considerat un limbaj de programare de nivel scăzut , spre deosebire de limbajele de nivel înalt care nu sunt legate de o anumită implementare a unui sistem de calcul. Programele scrise în limbaj de asamblare se traduc fără ambiguitate în instrucțiunile unui anumit procesor și, în majoritatea cazurilor, nu pot fi portate fără modificări semnificative pentru a rula pe o mașină cu un set de instrucțiuni diferit. Un asamblator este un program care convertește codul limbajului de asamblare în cod mașină; un program care efectuează o sarcină inversă se numește dezasamblator .
Primii asamblatori au fost proiectați de Kathleen Booth în 1947 sub ARC2 [2] și de David Wheeler în 1948 sub EDSAC [3] , în timp ce termenul „asamblator” nu a fost folosit, numind pur și simplu limbajul „un set de instrucțiuni de bază”. " ( Setul de comenzi de bază în engleză ) și, respectiv, "comenzi inițiale" ( comenzi inițiale în engleză ). Pentru prima dată, termenul „asamblator” pentru procesul de combinare a câmpurilor într-un cuvânt de control a început să fie folosit de rapoartele ulterioare despre EDSAC.
De asemenea, în primele etape ale dezvoltării programării, a fost introdus conceptul de codare automată - un limbaj de programare, ale cărui propoziții sunt practic similare ca structură cu comenzile și datele procesate ale unui anumit limbaj de mașină [4][ semnificația faptului? ] . Termenul nu este folosit în prezent.
Din punct de vedere istoric, dacă codurile de mașină sunt considerate prima generație de limbaje de programare, atunci limbajul de asamblare poate fi considerat a doua generație de limbaje de programare. . Deficiențele limbajului de asamblare, de exemplu, dificultatea dezvoltării unor sisteme software mari pe acesta, au condus ulterior la apariția limbajelor de a treia generație - limbaje de programare de nivel înalt (cum ar fi Fortran , Lisp , Cobol , Pascal ). , C și altele).
Nu există o sintaxă a limbajului de asamblare folosită în mod obișnuit. Deoarece sistemele de instrucțiuni ale diferitelor procesoare diferă semnificativ, limbajele de asamblare pentru aceste procesoare diferă și ele. În plus, fiecare program de asamblare poate folosi o sintaxă diferită. În asamblatoarele pentru procesoare x86 , așa-numita sintaxă Intel este cea mai utilizată și, într-o măsură mai mică, sintaxa AT&T .
Construcția de bază a limbajului de asamblare este un cod mnemonic sau mnemonic - o scurtă reprezentare simbolică a unei instrucțiuni de procesor. De regulă, este format din mai multe caractere care indică acțiunea care trebuie întreprinsă (de exemplu, movpentru a trece dintr-un registru în altul, addpentru a adăuga valori etc.). De asemenea, mnemonicul poate include obiectul asupra căruia se efectuează operația (registru, memorie, stivă) sau alte caracteristici (influență asupra registrului steagurilor , condiții de execuție etc.), totuși, în alte dialecte, aceleași caracteristici pot fi specificat în operanzi.
De regulă, asamblatorul fiecărui procesor are propriul set tradițional de mnemonici, dar există asamblatori cu sintaxă multiplatformă (cum ar fi sintaxa AT&T), cu toate acestea, numai notațiile rămân multiplatforme în ele, codul unui procesor. nu poate fi transferat direct altuia.
Ca operanzi pot fi specificate registre, valori constante, adrese ale celulelor de memorie și porturi I/O , constante, etichete etc. Asambleri diferiți pot necesita o ordine diferită a operanzilor: în unele implementări, operatorul în care este scrisă valoarea este primul, în altele acesta este ultimul. De regulă, operanzii sunt separați de mnemonicii instrucțiunilor prin spații.
Cel mai comun tip de date cu care pot lucra majoritatea procesoarelor este un număr întreg împachetat într-un cuvânt de mașină sau unul sau mai mulți octeți , mai rar un număr în virgulă mobilă . În programele în limbaj de asamblare, valorile date în diferite sisteme numerice sunt mult mai des folosite. În primul rând, în computerele cu un octet de opt biți, notația hexazecimală este adesea folosită , deoarece două cifre hexazecimale sunt plasate într-un octet. Unele valori pot fi scrise în coduri binare. La primele calculatoare cu un octet de șase biți, a fost întâlnit și sistemul de numere octale . Metodele de scriere pot diferi în diferite asamblare, de exemplu:
În plus, uneori este necesară specificarea blocurilor de date care sunt încărcate împreună cu codul programului, pentru care asamblatorul poate conține directive specializate. Asamblerii moderni pot sprijini, de asemenea, organizarea datelor sub forma diferitelor structuri .
Asamblerii pot suporta diverse constructe pentru a face codul de asamblare mai ușor de citit, pentru a scuti programatorul de nevoia de a ține evidența adreselor de instrucțiuni și pentru a implementa elemente care sunt specifice limbajelor de nivel înalt.
De regulă, codul de asamblare nu utilizează indentare și paranteze operator caracteristice limbajelor de nivel înalt . Codul de asamblare este de obicei scris în mai multe coloane, care includ:
Acest mod de scriere reflectă particularitatea execuției programelor pe procesoare de uz general: la nivelul codurilor de mașină, programele sunt de obicei liniare, nu au structură și dintr-un loc în program se poate face o tranziție în alta, indiferent de unde se află începutul codului programului şi programul va continua execuţia din acel punct.locul unde s-a făcut transferul. Un exemplu de program în limbaj de asamblare pentru arhitectura PIC16 :
Din nou: movf 0x40 , W ; Copiați locația 0x40 (zecimală 64) în registrul W addlw 0x05 ; Adăugați constanta 5 în registrul W movwf PORTC ; Scrieți registrul W în portul de ieșire PORTC al microcontrolerului clrw ; ștergeți registrul W (această instrucțiune nu are operanzi) mergeți la Din nou ;Mergi la etichetă din nouDeoarece codul de asamblare este tradus fără ambiguitate în cod de mașină pentru un anumit procesor, acest lucru vă permite să utilizați mai pe deplin toate capacitățile procesorului, să reduceți numărul de operațiuni inutile „inactiv” și să utilizați alte metode de optimizare a codului de program care nu sunt disponibile. atunci când se utilizează compilatoare, totuși, dezvoltarea compilatoarelor de optimizare duce la faptul că calitatea codului pe care îl generează poate fi mai mare decât o poate scrie un programator de asamblare moderat calificat [5] . Mai mult, cu cât volumul programului este mai mare, cu atât câștigul din utilizarea limbajului de asamblare este mai mic.
Programele în limbaj de asamblare nu permit comportament nedefinit , cu toate acestea, în general, scrierea și depanarea codului în asamblare necesită mai mult efort. Controlul tipului nu este disponibil în assembler , motiv pentru care semnificația unei anumite valori și acțiunile permise asupra acesteia trebuie să fie controlate de programator însuși. Când scrieți programe în limbaj de asamblare, este necesară utilizarea constantă a stivei și a unui număr limitat de registre de uz general, precum și a indicatorilor, ceea ce necesită ca programatorul să fie atent și să aibă o memorie bună.
Programele în limbaj de asamblare sunt aproape imposibil de portat la o mașină cu o arhitectură sau un set de instrucțiuni diferite fără a rescrie programul, chiar dacă la scriere a fost folosit un dialect în limbaj de asamblare „mult-platformă”: arhitecturi diferite de procesor au seturi diferite de registre, steaguri, diferite dimensiuni de cuvinte ale mașinii și pot avea, de asemenea, comenzi foarte specializate care nu sunt disponibile pe alte platforme.
Programul de asamblare are mai multe oportunități de a interacționa cu hardware-ul și cu nucleul sistemului de operare . De exemplu, la primele computere de acasă și console de jocuri, s-ar putea să nu fi existat un temporizator încorporat cu o rezoluție suficient de mare, dar, în același timp, frecvența de ceas a procesorului era standard pentru toate dispozitivele de același tip, ceea ce a făcut posibilă să folosească procesorul ca temporizator, numărând numărul de cicluri pentru a executa anumite comenzi și inserând operații goale în locurile potrivite. În procesoarele moderne care utilizează circuite de optimizare a performanței încorporate, modificări dinamice ale frecvenței de ceas și sisteme complexe de întrerupere, și cu atât mai mult sub controlul sistemului de operare multitasking , astfel de tehnici au devenit imposibile, dar continuă să fie utilizate pe unele microcontrolere .
Apariția asamblatorilor a facilitat foarte mult sarcina de programare a calculatoarelor timpurii, dar destul de repede complexitatea problemelor aplicate a necesitat utilizarea unor limbaje de nivel înalt. Cu toate acestea, aceste limbi au fost executate destul de lent și, în plus, nu au avut întotdeauna acces la toate capabilitățile hardware ale computerului. Pe măsură ce performanța mainframe-urilor și minicalculatoarelor au crescut și odată cu apariția limbilor precum C , relevanța limbajului de asamblare a început să scadă, dar a crescut din nou odată cu apariția microcalculatoarelor . De regulă, microprocesoarele timpurii aveau performanțe scăzute și o cantitate mică de memorie RAM disponibilă și, în plus, compilatoarele de limbi de înaltă calitate pentru limbaje de nivel înalt nu au apărut imediat pentru ei. Adesea, programele pentru computerele de acasă, inclusiv jocurile, au fost scrise în întregime în asamblator. Cu toate acestea, până la începutul secolului 21, compilatoarele de optimizare au fost adăugate la performanța în creștere a computerelor , ceea ce a generat un cod de mașină care a fost mai optim decât ar putea scrie un programator mediu. În plus, problema portabilității între diferite platforme a devenit importantă.
Limbajul de asamblare este folosit și în depanare și inginerie inversă , folosind programe de dezasamblare . Folosind dezasamblatorul, puteți controla execuția programului la nivelul instrucțiunilor mașinii, ceea ce este util, de exemplu, atunci când căutați locuri cu comportament nedefinit sau erori care apar atunci când lucrați cu pointeri.
Pentru a facilita dezvoltarea, a fost utilizată următoarea abordare: cea mai mare parte a codului este scrisă într-un limbaj de nivel înalt și numai secțiunile pentru care performanța este critică sau care necesită acces direct la resursele hardware ale computerului sunt scrise în asamblator.
Acest program trimite înapoi un caracter primit prin portul serial UART ("Echo"):
mov SCON , #50 h mov TH1 , #0 FDh orl TMOD , #20 h setb TR1 din nou: clr RI jnb RI , $ mov A , SBUF jnb RI , $ clr TI mov SBUF , A jnb TI , $ sjmp din nou Exemple de compilare a C în limbajul de asamblare pentru arhitectura ARMOperații cu biți:
C:
z = ( a << 2 ) | ( b & 15 );Asamblator:
ADR r4 , a ; obține adresa pentru un LDR r0 ,[ r4 ] ; obține valoarea unui MOV r0 , r0 , LSL #2 ; efectuează schimbul ADR r4 , b ; obține adresa pentru b LDR r1 ,[ r4 ] ; obțineți valoarea lui b ȘI r1 , r1 , #15 ; executa AND ORR r1 , r0 , r1 ; executa OR ADR r4 , z ; obține adresa pentru z STR r1 ,[ r4 ] ; stocați valoarea pentru zRamuri:
C:
dacă ( i == 0 ) { i = i + 10 ; }Asamblator:
@(variabila i este în registrul R1 ) SUBS R1 , R1 , #0 ADDEQ R1 , R1 , #10Cicluri:
C:
pentru ( i = 0 ; i < 15 ; i ++ ) { j = j + j _ }Asamblator:
SUB R0 , R0 , R0 ; i -> R0 și i = 0 start CMP R0 , #15 ; sunt < 15? ADDLT R1 , R1 , R1 ; j = j + j ADDLT R0 , R0 , #1 ; i++ BLT start Program pentru microcontroler PIC16F628A ( arhitectura PIC )În cazul în care 8 LED-uri sunt conectate la portul PORTB al microcontrolerului, programul le va porni după una:
LISTA p = 16 F628A __CONFIG 0309 H STATUS equ 0x003 RP0 equ 5 TRISB equ 0x086 PORTB equ 0x006 ORG 0x0000 ;Start vectorul du -te la start ;Sari la începutul codului principal start: bsf STATUS , RP0 ;Select bank 1 clrf TRISB ;Toți biții PORTB sunt ieșiți bcf STATUS , RP0 ;Select bank 0 led: movlw .170 ;Scrieți valoarea binară " 10101010 " în PORTB movwf PORTB ; Loop to PORTB; Sfârşit Program pentru microcontroler MSP430G2231 ( arhitectura MSP430 ) în Code Composer Studio .cdecls C , LIST , "msp430g2231.h" ;-------------------------------------- -------------- ------------------------------------ ---- .text ; Pornirea programului ;----------------------------------------------- ------ ------------------------------ RESET mov.w #0280 h , SP ; Inițializați stackpointer StopWDT mov.w #WDTPW+WDTHOLD,&WDTCTL ; Opriți WDT SetupP1 bis.b #001 h , & P1DIR ; Ieșire P1.0 ; Mainloop bit.b #010 h , & P1IN ; P1.4 mare/scăzut? jc ON ; jmp--> P1.4 este setat ; OFF bic.b #001 h , & P1OUT ; P1.0 = 0 / LED OFF jmp Mainloop ; ON bis.b #001 h , & P1OUT ; P1.0 = 1 / LED ON jmp Mainloop ; ; ;------------------------------------------------- ------------------------------ ; Vectori de întrerupere ;----------------------------------------------- ------ ------------------------------- .sect ".reset" ; MSP430 RESET Vector .scurt RESET ; .Sfârşitlimbaj de asamblare | |
---|---|
IDE | |
Traducători | |
Formate de sintaxă |
Limbaje de programare | |
---|---|
|