Il linguaggio assembly è un linguaggio di programmazione di basso livello linguaggio di programmazione che espone le istruzioni utilizzate dal computer per gestire il proprio hardware. In questo articolo, esploriamo il linguaggio assembly come introduzione alla programmazione con esempi e spiegazioni di codice. Se ti sei mai chiesto cosa sia un “puntatore” o “stack” e se dovresti imparare l’assembly nel tuo percorso per diventare un programmatore, continua a leggere. Questo articolo spiega cos’è il linguaggio assembly, i suoi vantaggi e svantaggi, esempi di casi d’uso comuni per i linguaggi assembly e alcune risorse se vuoi saperne di più su questo argomento. Iniziamo!
Definizione del linguaggio assembly
Il linguaggio assembly è un linguaggio di programmazione di basso livello specifico per un particolare tipo di processore. Di solito è scritto in forma mnemonica, che è una rappresentazione simbolica del codice macchina generato dall’assemblatore. Nel linguaggio assembly, gli opcode delle istruzioni macchina sono sostituiti da mnemonici e gli indirizzi delle istruzioni o degli operandi sono sostituiti da simboli di indirizzo o etichette. Su dispositivi diversi, il linguaggio assembly corrisponde a diversi set di istruzioni del linguaggio macchina e viene convertito in istruzioni macchina attraverso il processo di assemblaggio. Esiste una corrispondenza uno a uno tra un linguaggio assembly specifico e un set di istruzioni del linguaggio macchina specifico e non è direttamente portabile tra piattaforme diverse.
Storia del linguaggio assembly
La storia del linguaggio assembly risale ai primi giorni dell’informatica. Uno dei primi linguaggi assembly è stato creato negli anni ’50 per il computer IBM 701. Questo linguaggio, chiamato Autocode, è stato sviluppato da Alick Glennie ed era basato sul codice esistente utilizzato per il predecessore del 701, l’IBM 650.
Autocode fu presto seguito da una serie di altri linguaggi assembly, tra cui FORTRAN Assembly Language (FAL) e COBOL Assembly Language (CAL). Questi linguaggi sono stati progettati per semplificare la programmazione nei rispettivi linguaggi di alto livello e hanno avuto molto successo.
Linguaggio di programmazione
Dall’avvento del primo computer elettronico al mondo nel 1946, il modo e il linguaggio di comunicazione tra esseri umani e macchine sono diventati la principale direzione di ricerca di ingegneri del software e professionisti informatici. Linguaggi di programmazione più efficienti e semplici sono diventati la nuova preferenza degli ingegneri del software. Con il rapido sviluppo dei computer, la velocità di aggiornamento dell’hardware dei computer sta diventando sempre più veloce e i requisiti per i linguaggi di programmazione stanno diventando sempre più rigorosi. I linguaggi di programmazione hanno fatto molta strada negli ultimi decenni e finora ci sono state 3 generazioni di linguaggi. Per soddisfare i requisiti di programmazione e le funzioni software in diversi campi, un gran numero di linguaggi di programmazione ha subito il processo di modifica, sostituzione e sviluppo, e alla fine si è sviluppato nella diversificazione degli attuali linguaggi di programmazione. Nonostante molti tentativi di trovare un linguaggio universale che possa adattarsi a tutti gli ambienti di programmazione, nessuno di essi ha avuto successo. Il linguaggio di programmazione sta avanzando con la tecnologia moderna e la saggezza dell’umanità si sta manifestando sempre di più.

1a generazione: linguaggio macchina
Il linguaggio macchina è il primo linguaggio di programmazione di generazione. All’inizio dell’invenzione del computer, per controllare il computer affinché completasse i propri compiti o progetti, le persone potevano scrivere solo stringhe binarie di numeri come “0” e “1” per controllare il computer. Questo linguaggio è il linguaggio macchina. Intuitivamente, il linguaggio macchina è molto oscuro e difficile da capire, e il suo significato è spesso compreso consultando tabelle o manuali. È molto doloroso da usare, soprattutto quando è necessario modificare il programma completato. Questo tipo di linguaggio macchina disordinato ti impedirà di iniziare ed è difficile trovare errori di programma. Inoltre, l’ambiente operativo di computer diversi è diverso e anche le istruzioni e i metodi operativi sono diversi. Quindi, quando hai una specificità in questo linguaggio macchina, puoi eseguirlo solo su un computer specifico. E una volta cambiato il computer, è necessario riprogrammare, il che riduce notevolmente l’efficienza dell’uso e della promozione del programma. Tuttavia, grazie alla specificità del linguaggio macchina, è perfettamente adattato a un tipo specifico di computer, quindi la sua efficienza operativa è molto più alta rispetto ad altri linguaggi.

2a generazione: linguaggio assembly
Non è difficile vedere che il linguaggio macchina, come linguaggio di programmazione, ha scarsa flessibilità e leggibilità. Per alleviare il disagio causato dal linguaggio macchina agli ingegneri del software, le persone hanno aggiornato e migliorato il linguaggio macchina: utilizzare alcune lettere facili da capire e ricordare, parole al posto di una specifica istruzione. Con questo metodo, è facile per le persone leggere il programma completato o comprendere la funzione che il programma sta eseguendo, e la correzione di bug e la manutenzione del programma esistente diventano più facili e convenienti. Questo linguaggio è quello che chiamiamo linguaggio assembly, il secondo linguaggio informatico di generazione.

Rispetto al linguaggio macchina, il linguaggio assembly ha una maggiore dipendenza dalla macchina ed è più facile da ricordare e scrivere, ma allo stesso tempo mantiene l’alta velocità e l’alta efficienza del linguaggio macchina. Il linguaggio assembly è ancora un linguaggio orientato alla macchina, è difficile capire l’intenzione del progetto del programma dal suo codice e il programma progettato non è facile da trasportare, quindi non è ampiamente utilizzato come la maggior parte degli altri linguaggi informatici di alto livello. Pertanto, nei linguaggi di alto livello altamente sviluppati di oggi, viene solitamente utilizzato a livello inferiore, di solito per l’ottimizzazione del programma o il funzionamento dell’hardware.
3a generazione: linguaggio di alto livello
Dopo che il linguaggio di programmazione ha subito l’aggiornamento del linguaggio macchina, del linguaggio assembly, ecc., le persone hanno scoperto il fattore chiave che limita la generalizzazione dei programmi: la portabilità del programma. È necessario progettare un programma che possa essere eseguito su macchine diverse indipendentemente dall’hardware del computer. In questo modo, è possibile evitare molti processi ripetitivi di programmazione e migliorare l’efficienza. Allo stesso tempo, il linguaggio dovrebbe essere vicino al linguaggio matematico o al linguaggio naturale degli esseri umani. Negli anni ’50, quando i computer erano ancora scarsi, nacquero i primi linguaggi di programmazione di alto livello. A quel tempo, il costo dei computer era elevato, ma la quantità di calcolo al giorno era limitata. Come utilizzare efficacemente la potenza di calcolo limitata dei computer è diventato un problema che le persone affrontavano in quel momento. Allo stesso tempo, a causa della scarsità di risorse, l’efficienza operativa dei computer è diventata anche l’obiettivo perseguito dagli ingegneri di quell’epoca.

Composizione del linguaggio assembly
A causa dell’enorme sistema di istruzioni di assemblaggio, è necessario costruire un sistema di istruzioni di sistema, che ha un gran numero di istruzioni, formati complessi e scarsa memorizzabilità. La parte più difficile dell’istruzione è la modalità di indirizzamento supportata dall’istruzione e la sua essenza è come ottenere l’operando nell’istruzione. Per il processore, si tratta di come trovare i dati di cui ha bisogno. Tuttavia, per il linguaggio assembly alla base del computer, questo metodo di indirizzamento comporterà un gran numero di formati di archiviazione di calcolo e sarà strettamente correlato al complesso metodo di gestione dell’archiviazione, quindi è difficile da capire. Infine, le istruzioni di assemblaggio sono anche correlate a come influenzare i flag, ma i flag del processore sono molto complessi, quindi è più difficile comprendere il meccanismo.
invia comando
Le istruzioni di invio del comando includono:
- istruzione generale di trasferimento dati: MOV;
- istruzione di trasferimento condizionale: CMOVcc;
- istruzione di operazione dello stack: PUSH, PUSHA, PUSHAD, POP, POPA, POPAD;
- istruzione di scambio: XCHG, XLAT, BSWAP;
- istruzione di trasferimento del selettore del descrittore di indirizzo o segmento: LEA, LDS, LES, LFS, LGS, LSS, ecc.
operazione logica
Questa parte delle istruzioni viene utilizzata per eseguire operazioni aritmetiche e logiche, tra cui:
- istruzione di addizione: ADD, ADC;
- istruzione di sottrazione: SUB, SBB;
- istruzione più uno: INC;
- istruzioni di aggiustamento decimale: AAA, AAS, DAA, DAS;
- istruzione meno uno: DEC;
- istruzione di operazione di confronto: CMP;
- istruzioni di estensione del segno: CBW, CWDE, CDQE;
- istruzione di moltiplicazione: MUL, IMUL;
- istruzione di divisione: DIV, IDIV;
- istruzioni di operazione logica: AND, NOT, OR, XOR, TEST.
istruzione di spostamento
Questa parte dell’istruzione viene utilizzata per spostare un operando di registro o di memoria un numero specificato di volte.
- istruzione di spostamento logico a sinistra: SHL;
- istruzione di spostamento logico a destra: SHR;
- istruzione di spostamento aritmetico a sinistra: SAL;
- istruzione di spostamento aritmetico a destra: SAR;
- istruzione di spostamento circolare a sinistra: ROL ;
- istruzione di spostamento circolare a destra: ROR, ecc.
manipolazione dei bit
Questa parte delle istruzioni include:
- l’istruzione di test del bit: BT;
- l’istruzione di test e impostazione del bit: BTS;
- l’istruzione di test e reset del bit: BTR;
- l’istruzione di test e negazione del bit: BTC;
- l’istruzione di scansione in avanti del bit: BSF;
- l’istruzione di scansione all’indietro del bit: BSR.
trasferimento di controllo
Questa parte include:
- istruzione di trasferimento incondizionato: JMP;
- istruzione di trasferimento condizionale: JCC, JCXZ;
- istruzione di ciclo: LOOP, LOOPE, LOOPNE;
- istruzione di chiamata di procedura: CALL;
- istruzione di ritorno della sottoprocédure: RET;
- istruzione di interrupt: INTn, INT3, INTO, IRET e così via.
Manipolazione di stringhe
Questa parte delle istruzioni viene utilizzata per operare sulla stringa di dati, tra cui:
- l’istruzione di trasferimento di stringhe: MOVS;
- l’istruzione di confronto di stringhe: CMPS;
- l’istruzione di scansione di stringhe: SCANS;
- l’istruzione di salvataggio di stringhe: STOS;
- l’istruzione di caricamento di stringhe: LODS.
Input Output
Questa parte delle istruzioni viene utilizzata per scambiare dati con dispositivi periferici, incluse le istruzioni di input della porta IN/ INS, le istruzioni di output della porta OUT/OUTS.
Esempio di linguaggio Assembly
Ecco un semplice programma in linguaggio Assembly che sommerà due numeri:
; add.asm
;
; This program adds two numbers together
;
section .data
; These are the two numbers we will be adding
; We must store them in memory so the CPU can access them
num1: dw 1234
num2: dw 5678
section .text
; This is the code section of the program
; The code is a set of instructions for the CPU to execute
global _start
_start:
; Load the two numbers into registers
mov eax, [num1]
mov ebx, [num2]
; Add the numbers together
add eax, ebx
; Store the result in the num1 memory location
mov [num1], eax
; Exit the program
mov eax, 1
int 0x80
Caratteristiche del linguaggio Assembly
1. dipendenza dalla macchina
Questo è un linguaggio di basso livello orientato alla macchina, solitamente progettato per un particolare computer o famiglia di computer. Poiché è una rappresentazione simbolica delle istruzioni macchina, macchine diverse hanno linguaggi Assembly diversi.
2. Alta velocità e alta efficienza
Il linguaggio Assembly mantiene i vantaggi del linguaggio macchina e ha le caratteristiche di immediatezza e semplicità. Può accedere e controllare efficacemente vari dispositivi hardware del computer, come dischi, memoria, CPU, porte I/O, ecc., e occupa meno memoria e ha una velocità di esecuzione rapida, è un linguaggio di programmazione efficiente.
3. La complessità della scrittura e del debug
Poiché l’hardware è controllato direttamente e anche le attività semplici richiedono molte istruzioni in linguaggio Assembly, è necessario coprire tutti gli aspetti quando si progettano i programmi. Tutti i possibili problemi devono essere considerati e varie risorse software e hardware devono essere allocate e utilizzate in modo ragionevole. In questo modo, aumenterà inevitabilmente il carico di lavoro del programmatore. Allo stesso modo, quando si esegue il debug di un programma, una volta che si verifica un problema con il funzionamento del programma, è difficile da individuare.
Vantaggi
In quanto linguaggio di programmazione di seconda generazione superiore al linguaggio macchina, il linguaggio Assembly ha anche molti vantaggi:
- Può leggere facilmente lo stato della memoria e lo stato dell’interfaccia I/O hardware.
- Il codice scritto può essere eseguito con precisione perché ci sono molti meno collegamenti di compilazione.
- In quanto linguaggio di basso livello, è altamente estensibile.
Svantaggi
- Poiché il codice è molto monotono e ci sono pochi caratteri di istruzioni speciali, rende il codice prolisso e difficile da scrivere.
- Poiché l’Assembly deve ancora chiamare la memoria per memorizzare i dati da solo, è facile avere bug ed è difficile da eseguire il debug.
- Anche se un programma viene completato, ci vorrà molto tempo per mantenerlo in seguito.
- A causa della particolarità della macchina, viene causato il difetto della scarsa compatibilità del codice.
Linguaggio Assembly vs Linguaggio macchina
La principale differenza tra linguaggio Assembly e linguaggio macchina è che il linguaggio Assembly è un linguaggio di programmazione di basso livello che richiede un assembler separato per tradurlo in codice macchina, mentre il linguaggio macchina è una rappresentazione diretta del codice macchina sottostante.
Il linguaggio Assembly è più leggibile per l’uomo rispetto al linguaggio macchina, ma è comunque abbastanza difficile da leggere e scrivere. È progettato per essere vicino al codice macchina nativo, rendendo facile per il programmatore capire cosa sta facendo il codice. Tuttavia, questo lo rende anche più difficile da scrivere codice portabile, poiché il codice è strettamente legato all’architettura specifica della macchina.
Il linguaggio macchina, d’altra parte, è il codice nativo per la macchina e non è leggibile dagli esseri umani. Viene eseguito direttamente dal processore ed è quindi più efficiente del linguaggio Assembly. Tuttavia, è molto più difficile da programmare, poiché il programmatore deve avere a che fare con le istruzioni del codice macchina sottostante.
Risorse per l'apprendimento del linguaggio Assembly
Se vuoi saperne di più sull’assembly language, sono disponibili molte risorse diverse. Puoi trovare libri sull’assembly language su Amazon e nelle librerie locali. Puoi anche trovare corsi online su siti web come Coursera, edX e Udemy. Se vuoi saperne di più sull’architettura dei computer, ci sono molti libri anche su questo argomento. Queste risorse possono aiutarti a capire cos’è l’assembly language e le sue implicazioni sulla progettazione hardware e software dei computer.




