Corso di Calcolatori Elettronici I A.A. 2010-2011 Introduzione al linguaggio assembly Lezione 20 Università degli Studi di Napoli Federico II Facoltà di Ingegneria Il linguaggio Assembly • È funzionalmente equivalente al linguaggio macchina, ma usa nomi più intuitivi (mnemonics) • Definisce l Instruction Set Architecture (ISA) della macchina • Un compilatore traduce un linguaggio di alto livello, che è indipendente dall architettura, in linguaggio assembly, che è dipendente dall architettura • Un assemblatore traduce programmi in linguaggio assembly in codice binario eseguibile • Nel caso di linguaggi compilati (es. C) il codice binario viene eseguito direttamente dalla macchina target • Nel caso di linguaggi interpretati (es. Java) il bytecode viene interpretato dalla Java Virtual Machine, che – in questo senso – è al livello Assembly language Ciclo di Sviluppo di un programma in C++ Editor disco Programma sorgente (nome.cpp) Preprocessore disco Compilatore disco Programma sorgente (nome.cpp) Programma sorgente (nome.obj) Librerie (object files) disco Collegatore disco Caricatore MEMORIA (RAM) Fase 1 preparazione del testo origine … il testo origine viene digitato mediante un editor e viene memorizzato in un file con estensione cpp Fase 2 precompilazione … il testo origine (sorgente) contenuto nel file .cpp viene elaborato da un programma detto preprocessore (o precompilatore) che sostanzialmente esegue l espansione del codice (inclusioni, macro, etc.) Fase 3 compilazione delle unità … le unità del programma vengono compilate mediante l attivazione del compilatore; il testo origine verrà trasformato in testo oggetto e memorizzato in un file con estensione .obj Fase 4 collegamento (linkage) … i diversi moduli oggetto costituenti il programma eseguibile vengono collazionati fra loro (p1.obj,…, pn.obj) e con il supporto al tempo di esecuzione mediante un modulo collegatore (linker). Il tutto viene memorizzato in un file che costituisce il programma eseguibile (p.exe) Linguaggi e dipendenza dalla piattaforma di esecuzione Codice C++ Compilatore C++ i386 Win OS Compilatore C++ PowerPC MacOS Compilatore C++ SPARC Solaris OS Codice Binario Pentium Win OS Codice Binario PowerPC MacOS Codice Binario SPARC Solaris OS Ciclo di sviluppo/esecuzione per programmi in linguaggio di alto livello Digitazione dei sorgenti Editor Compilatore Moduli oggetto Programma sorgente Linker statico Programma in linguaggio macchina in RAM Debugger Macchina target Loader / Linker dinamico Programma eseguibile Ciclo di sviluppo/esecuzione per programmi in linguaggio assembly Digitazione dei sorgenti Editor Assemblatore Moduli oggetto Programma sorgente Linker statico Programma in linguaggio macchina in RAM Debugger Macchina target Loader / Linker dinamico Programma eseguibile Ciclo di sviluppo semplificato di programmi assembly MC68000 nel sistema didattico ASIM Digitazione del programma Editor Assembler Moduli oggetto e file list ASIMTOOL Programma sorgente .a68 Macchina target Loader ASIM Assembly: formato del codice sorgente • Una linea di codice sorgente Assembly è costituita da quattro campi: – LABEL Ø Stringa alfanumerica Ø Definisce un nome simbolico per il corrispondente indirizzo – OPCODE Ø Codice mnemonico o pseudo-operatore Ø Determina la generazione di un istruzione in linguaggio macchina o la modifica del valore corrente del Program Location Counter – OPERANDS Ø Oggetti dell azione specificata dall OPCODE Ø Variano a seconda dell OPCODE e del modo di indirizzamento – COMMENTS Ø Testo arbitrario inserito dal programmatore Assembly: caratteristiche generali • Di regola, una linea di codice assembly corrisponde ad una istruzione l/m • Eccezioni: – Macro: 1 linea assembler → n istruzioni l/m – Pseudo istruzioni: 1 linea assembler → 0 istr. l/m • Variabili interamente gestite dal programmatore – Allocazione: memoria o registri CPU – No dichiarazione Esempio – Assembly X86 a 32 bit DES_std_crypt: movl 4(%esp),%edx pushl %ebx movl DES_count,%ecx xorl %ebx,%ebx movq (%edx),K1 movq 32(%edx),K2 movq K1,tmp1 movq 8(%edx),K3 movq 16(%edx),K4 DES_copy(24, 40) … DES_copy(112, 120) movq DES_IV,R xorl %edx,%edx movq DES_IV+8,L DES_loop: … Esempio – Assembly Alpha DES_std_crypt: ldgp $29,0($27) DES_std_crypt..ng: subq $30,56,$30 lda tmp1,DES_IV lda tmp2,DES_count lda SPE,DES_SPE_F ldq R,0(tmp1) ldq L,8(tmp1) ldq count,0(tmp2) ldq K1,0(kp) ldq K2,8(kp) ldq K3,16(kp) ldq K4,24(kp) xor K1,R,D ldq K5,32(kp) ldq K6,40(kp) ldq K7,48(kp) … ldq K8,56(kp) stq K9,0($30) stq K10,8($30) stq K11,16($30) stq K12,24($30) stq K13,32($30) stq K14,40($30) stq K15,48($30) ldq K9,64(kp) ldq K10,72(kp) ldq K11,80(kp) ldq K12,88(kp) ldq K13,96(kp) ldq K14,104(kp) ldq K15,112(kp) ldq K16,120(kp) DES_loop: DES_2_ROUNDS(K2, K3) … Esempio – Assembly SPARC DES_std_crypt: … save %sp,-120,%sp st %i7,[%fp-24] sethi %hi(DES_SPE_L),SPE_L_0 sethi %hi(DES_SPE_L+0x400),SPE_L_4 add SPE_L_0,0x808,SPE_H_0 … ldd [kp],Dl ldd [SPE_L_4+0xC08],Rl … ld [SPE_L_4+0xC18],count DES_loop: DES_2_ROUNDS(kp) … std Rl,[out] std Ll,[out+8] ret restore … Linguaggi Assembly • Per una data macchina, esiste sempre almeno il linguaggio assembly definito dal costruttore • In aggiunta, possono esistere linguaggi assembly forniti da terze parti • Quando si definisce un linguaggio assembly – Si ha libertà di scelta per quanto riguarda: • Gli mnemonics • Il formato delle linee del sorgente • I formati per specificare modi di indirizzamento, varianti delle istruzioni, costanti, label, pseudo-operatori, etc. – Non si ha libertà di scelta per quanto riguarda: • L effetto finale di ogni singola istruzione macchina Convenzioni • Gli spazi bianchi tra i diversi campi fungono esclusivamente da separatori (vengono ignorati dall assemblatore) • Una linea che inizi con un asterisco (*) è una linea di commento • Nelle espressioni assembly, gli argomenti di tipo numerico si intendono espressi – In notazione decimale, se non diversamente specificato – In notazione esadecimale, se preceduti dal simbolo $ • Nell indicazione degli operandi, il simbolo # denota un indirizzamento immediato Program Location Counter PLC Ø E una variabile interna dell assemblatore Ø Punta alla locazione di memoria in cui andrà caricata – a run time – l istruzione assemblata Ø Viene inizializzato dallo pseudo-operatore origin (ORG) Ø Durante il processo di assemblaggio, il suo valore è aggiornato sia in funzione degli operatori, sia in funzione degli pseudo-operatori Ø E possibile, all interno di un programma, fare riferimento al suo valore corrente, mediante il simbolo * AsimTool AsimTool: esempio di file list PLC 00000000 00000000 00008000 00008000 00008006 0000800C 00008012 00008018 0000801E 00008024 00008028 0000802A 00008030 00008030 00008032 00008034 00008034 contenuto label 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 4279 00008032 3039 00008034 33C0 00008030 D079 00008032 33C0 00008032 3039 00008030 0640 FFFF 66E2 4EF9 00008008 =00008008 =00000011 0011 opcode operands comments * Somma i primi 17 interi * ORG $8000 START CLR.W SUM MOVE.W ICNT,D0 ALOOP MOVE.W D0,CNT ADD.W SUM,D0 MOVE.W D0,SUM MOVE.W CNT,D0 ADD.W #-1,D0 BNE ALOOP JMP SYSA SYSA EQU $8008 CNT DS.W 1 SUM DS.W 1 IVAL EQU 17 ICNT DC.W IVAL Symbol Table ALOOP START 800C 8000 CNT SUM 8030 8032 IVAL ICNT 0011 8034 ASIM: programma caricato in memoria Pseudo-operatori • NON sono istruzioni eseguite dal processore – sono direttive che regolano il processo di traduzione del programma assembler in programma eseguibile • Lo pseudo-operatore ORG – Viene usato per inizializzare il Program Location Counter (PLC), ovvero per indicare a quale indirizzo sarà posta la successiva sezione di codice o dati – Esempio: ORG $8100 • Lo pseudo-operatore END – Viene usato per terminare il processo di assemblaggio ed impostare l entry point (prima istruzione da eseguire) nel programma – Esempio: END TARGETLAB Pseudo-operatori • Lo pseudo-operatore DS – Viene usato per incrementare il Program Location Counter (PLC), in modo da riservare spazio di memoria per una variabile – Esempio: LABEL DS.W NUMSKIPS • Lo pseudo-operatore DC – Viene usato per inizializzare il valore di una variabile – Esempio: LABEL DC.W VALUE • Lo pseudo-operatore EQU – Viene usato per definire una costante usata nel sorgente assembler – Esempio: LABEL EQU VALUE Etichette (label) • Sono stringhe di testo arbitrarie (opzionali) anteposte ad una istruzione o ad un dato all interno del programma assembler • Servono a riferirsi al particolare indirizzo che contiene quella istruzione o dato – usati per gestire i salti – usati per gestire variabili (manipolate nel programma assembler attraverso le loro etichette in maniera simile alle variabili di un linguaggio di programmazione di alto livello) • Ad esempio: – ALOOP è un etichetta usata per riferisti all istruzione MOVE, SUM è una etichetta usata per gestire una variabile, mentre IVAL è una costante ALOOP MOVE.W D0,CNT ADD.W … … … … SUM DS.W IVAL EQU … … … … … … SUM,D0 1 17 Processori a carattere e processori a parola • I processori a carattere accedono alla memoria con parallelismo 1 byte (8 bit) – prime CPU ad accumulatore • I processori a parola hanno la capacità di indirizzare ed accedere la memoria per unità (parole o word) di 16 bit, 32 bit o 64 bit • In questi sistemi (tranne pochissime eccezioni nel passato) l unità indirizzabile di memoria (locazione) è ancora il byte – Si parla di sistemi a memoria byte-addressable: ogni byte ha il suo indirizzo • Terminologia Motorola 68000: word = 2 byte, longword = 4 byte Big-endian e little-endian • I processori a parola possono disporre in memoria i byte che formano una parola in due modi – Big-endian: i byte sono disposti in memoria in modo che il più significativo MSB occupi la locazione di memoria di indirizzo minore, e poi via via gli altri, fino a quello meno significativo LSB che è collocato nella locazione di indirizzo maggiore – Little-endian: disposizione opposta • Il processore Motorola 68000 usa la convenzione Big Endian Disposizione BIG_ENDIAN Byte3 Byte2 Byte1 Byte0 MSB LSB Indirizzi crescenti Disposizione LITTLE ENDIAN Byte0 Byte1 Byte2 Byte3 LSB MSB Indirizzi crescenti Big-endian e little-endian: un esempio • Immaginiamo di avere un processore a parola, con parole di 32 bit (4 byte) e voler scrivere in memoria il valore intero (esadecimale) $12FA34ED all indrizzo 812 • Le figure sottostanti illustrano il contenuto della memoria nei due casi big-endian e little-endian … 12 FA 34 ED … indirizzo … indirizzo big-endian ED 34 FA 12 … little-endian Memoria: parole allineate e non allineate • Per un processore a parola di 16 bit o 32 bit, una parola che inizia ad un indirizzo pari si dice allineata sul limite di parola • Tipicamente, un processore è in grado di accedere ai due byte che costituiscono una parola allineata mediante una sola operazione di lettura • Il processore Intel 8086 consente l accesso a parole non allineate, cioè parole che iniziano ad un indirizzo dispari, ma in tal caso sono necessari 2 distinti accessi in memoria • Il 68000 NON consente l accesso a parole non allineate Indirizzo i Indirizzo i+2 (i pari) i i+2 i+1 i+3 i+1 La parola di 16 bit formata dai due byte ombreggiati non è allineata sul limite di parola (indirizzo multiplo di 2) i+2 Esempio - Moltiplicazione 2 interi * Programma per moltiplicare MCND e MPY * * MULT LOOP DONE PROD MPY MCND ORG $8000 CLR.W MOVE.W BEQ ADD.W ADD.W BNE MOVE.W STOP ORG DS.W DC.W DC.W END D0 MPY,D1 DONE MCND,D0 #-1,D1 LOOP D0,PROD #$2700 $8200 1 3 4 MULT D0 accumula il risultato D1 e' il contatatore di ciclo Se il contatore e' zero e' finito Aggiunge MCND al prodotto parziale Decrementa il contatore e ripete il giro Salva il risultato Arresta esecuzione programma Riserva spazio di memoria per PROD Definisce il valore di MPY Definisce il valore di MCND Fine ass., salto a entry point Analisi del file LIS PLC 00000000 00000000 00008000 00008000 00008000 00008002 00008008 0000800C 00008012 00008016 00008018 0000801E 00008200 00008200 00008202 00008204 00008206 contenuto 4240 3239 6700 D079 0641 66F4 33C0 4E72 00008202 000E 00008204 FFFF 00008200 2700 0003 0004 label opcode operandi 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 * * Programma per moltiplicare MCND e MPY ORG * MULT LOOP DONE PROD MPY MCND CLR.W MOVE.W BEQ ADD.W ADD.W BNE MOVE.W STOP ORG DS.W DC.W DC.W END $8000 D0 MPY,D1 DONE MCND,D0 #-1,D1 LOOP D0,PROD #$2700 $8200 1 3 4 MULT Symbol Table MULT LOOP $8000 $800C MPY MCND $8202 $8204 DONE PROD $8018 $8200 Esercitazione • Provare il programma mult2ints.a68 che moltiplica due interi attraverso un ciclo di addizioni ripetute • Eseguire il programma sul simulatore ASIM e sperimentare: – – – – – – – – – – L effetto di DC e la convenzione big-endian del processore 68000 L effetto dell istruzione CLR .W su registro di 32 bit L effetto dell istruzione MOVE da memoria a registro L effetto dell istruzione BEQ sul PC L effetto dell istruzione ADD tra memoria e registro L effetto dell istruzione ADD tra immediato e registro L effetto dell istruzione BNE sul PC L effetto dell istruzione JMP sul PC L effetto dell istruzione MOVE da registro a memoria Confrontare la codifica in l/m delle istruzioni di salto Esercitazione • Nell esempio precedente, effettuare le seguenti sostituzioni ed osservarne gli effetti DONE MOVE.W D0,PROD Salva il risultato PROD PROD DS.W 1 Riserva spazio di memoria per DONE MOVE.L D0,PROD Salva il risultato PROD PROD DS.L 1 Riserva spazio di memoria per L= long (32 bit) W= word (16 bit) B= byte (8 bit)