Introduzione al linguaggio assembly del microprocessore 8086 Il linguaggio macchina Il linguaggio naturale di un microprocessore è il linguaggio macchina. Nel linguaggio macchina non esistono riferimenti astratti o simbolici e tutte le operazioni sono eseguite direttamente sui registri o in locazioni assolute di memoria. Il linguaggio macchina non è altro che l’insieme delle istruzioni definite per un particolare processore. Ogni istruzione è identificata dal suo codice, di solito riportato in binario o in esadecimale. Il linguaggio macchina Il linguaggio macchina si compone di istruzioni alle quali fanno immediatamente seguito i relativi operandi. Un esempio di linguaggio macchina per il processore Intel 8086 è il seguente codice per il confronto del contenuto dell’accumulatore AX con la costante 812h: 0011 1101 0001 0010 0000 1000 Per facilitare la descrizione delle istruzioni e degli operandi, si fa uso della notazione esadecimale in alternativa a quella binaria. L’esempio precedente assume in esadecimale questo aspetto: 3D1208 Con debug Con l’uso della calcolatrice scientifica potremo verificare che il valore binario corrispondente è proprio: 001111010001001000001000 Difficile? Resta però difficile lavorare anche con questa notazione. Il codice rimane indistinguibile dagli operandi e solo a fatica, con l’aiuto di una tabella di conversione si riconosce in 3D l’istruzione di confronto. Un certo impegno è anche necessario per la traduzione di 08 12 in 12 08. Infatti viene memorizzato prima il byte della parte bassa e poi il byte della parte alta del numero considerato a 16 bit. Molto !!! Il codice binario (o la sua rappresentazione equivalente esadecimale) usato nel linguaggio macchina è molto scomodo; per l’uomo è molto più facile raffigurare e lavorare con simboli e messaggi piuttosto che con cifre. Una soluzione: I linguaggi assembly in ambienti assembler sono stati introdotti proprio per eliminare i problemi di uso del linguaggio macchina. Le caratteristiche principali dei linguaggi assembly sono le seguenti: • In assembly le istruzioni non sono identificate da codici astratti ma da simboli letterali con significato mnemonico. ADD significa ad esempio addizione • • Alle variabili viene fatto riferimento per valore e non per locazione assoluta di memoria (indirizzo) E’ possibile definire istruzioni macro assembler, composte a loro volta da altre istruzioni, e richiamarle nel programma. ebp punta alla base dello STACK Esempio: alternativa In Linguaggio Assembly In Linguaggio C like (commenti in IDE jasmin) Esempio: scrittura a video ….. main(….) { System.out.print(“ciao \n”); } In Linguaggio JAVA ….. main(….) { printf(“ciao \n”); } In Linguaggio C In Linguaggio Assembly DSEG SEGMENT ;segmento dati Outstr db “ciao”,13,10,”$” DSEG ENDS SSEG SEGMENT stack ;segmento catasta dw 32 dup (?) SSEG ENDS CSEG SEGMENT ;segmento codice assume cs:cseg, ds:dseg, ss:sseg start: mov bx,dseg mov ds,bx ;DS=DSEG via bx mov dx,offset outstr ;puntatore a “ciao” mov ah,09h ;uscita su schermo int 21h ;richiamo MS-DOS mov ah,4Ch ;termine programma int 21h ;richiamo MS-DOS CSEG ENDS END start ; termine programma ; inizio a start Complicato? Il primo programma è molto più compatto del secondo, oltre che più facile da leggere e capire. Il programma in assembly è a prima vista certamente molto più complicato ed è necessario un certo tempo per analizzarne e comprenderne le funzioni, che in questo caso sono comunque molto semplici. Entrambi i programmi funzionano secondo lo stesso principio, chiedendo al sistema operativo di presentare una stringa sullo schermo. Dettagli nascosti o espliciti Nel programma in linguaggio JAVA i dettagli di questa chiamata sono nascosti al programmatore al quale è sufficiente scrivere l’istruzione Systm.out.print Spetta al compilatore generare la chiamata al sistema operativo, aggiungere alla stringa i codici di controllo “a capo” e “ritorno carrello”, ecc. Nel programma in assembly è necessario tenere esplicitamente conto di tutti questi aspetti. Le chiamate al sistema operativo hanno luogo per mezzo dell’istruzione INT 21h La stringa di uscita è definita nell’area dati; con essa devono essere indicati esplicitamente i codici di “a capo” (ASCII 10) , “ritorno carrello” (ASCII 13) e termine stringa “$”. La differenza di spazio occupato in memoria dai due programmi è evidente quando si passa a compilarli ed eventualmente collegarli. Facciamo qualche valutazione.. Le dimensioni in byte dei codici sorgente, oggetto (compilato) e eseguibile (collegato) dei programmi sono qui confrontate: Programma in JAVA Programma in C Programma in Assembly Sorgente 1000 byte 57 byte 682 byte Oggetto 1000 byte 578 byte 194 byte Al volo 15 Kbyte 610 byte Eseguibile La differenza nelle dimensioni del programma sorgente assembly rispetto al C è dovuta al maggior spazio richiesto per le istruzioni e per i commenti necessari. Il codice compilato è però già più compatto per il programma assembly. La differenza più rilevante si nota dopo che i programmi sono stati collegati alle rispettive biblioteche e routine di servizio: il programma in assembly manca quasi completamente di overhead, che invece caratterizza il programma in C. Il programma scritto in assembly è più rapido a caricarsi ed eseguirsi; tutti i programmi producono lo stesso risultato e non sono distinguibili solo sulla base di quest’ultimo. Confrontando ... Non esistono criteri assoluti per optare per un linguaggio ad alto livello oppure assembly. Se con l’assembly è possibile scrivere programmi più efficienti, è anche vero che la loro stesura prende molto più tempo rispetto allo scrivere programmi in un linguaggio avanzato. Anche la documentazione e la manutenzione di programmi assembly sono più difficili e dispendiose. La programmazione in assembly resta comunque di attualità in tutti i casi dove con la programmazione ad alto livello si raggiungono i limiti di capacità di memoria o velocità di esecuzione di una macchina. Alcune funzioni, in particolare quelle che agiscono direttamente sulle risorse del sistema, non sono realizzabili se non in assembly. Aspetto non trascurabile della programmazione assembly è il suo carattere didattico. Indipendentemente dal numero e tipo di prodotti software installati in un sistema, il processore, almeno con le architetture attuali, opera su istruzioni di macchina assimilabili a quelle di un programma assembly. L’assembly aiuta quindi a comprendere meglio i meccanismi di funzionamento della macchina. … concludendo … nell'evoluzione vs linguaggi di scripting