Introduzione al linguaggio assembly - ICAR-CNR

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)