• Non ci sono risultati.

Dispensa I.6

N/A
N/A
Protected

Academic year: 2021

Condividi "Dispensa I.6"

Copied!
20
0
0

Testo completo

(1)

Dispensa I.6 versione 1.0 mail: lamonica@associatesonline.it Pagina 1 di 20

PROGRAMMAZIONE ASSEMBLER

La dispensa di seguito proposta si pone come tutorial per poter porre le basi per la programmazione in ASSEMBLER.

Sarà di compendio il libro

PC Assembly Language, di Paul A. Carter” – disponibile per il download in italiano alla pagina http://www.drpaulcarter.com/pcasm/pcasm-book-italian-pdf.zip oppure disponibile sul sito della scuola.

Per poter sviluppare i programmi proposti sarà inoltre necessario scaricare l’ambiente di sviluppo DJGPP scaricabile alla pagina http://www.delorie.com/djgpp/zip-picker.cgi oppure disponibile sul sito della scuola in tre file .zip

- Ambiente_di_sviluppo_parte_1 - Ambiente_di_sviluppo_parte_2 - Ambiente_di_sviluppo_parte_3

Per installare l’ambiente di sviluppo è necessario avere i diritti di amministratore sulla macchina su cui si installa e leggere ATTENTAMENTE il documento HOWTO_INSTALL_DJGPP.txt disponibile sul sito della scuola.

(2)

Dispensa I.6 versione 1.0 mail: lamonica@associatesonline.it Pagina 2 di 20

AMBITO DI PROGRAMMAZIONE

Per facilitare lo studente l’ambiente di programmazione scelto è WINDOWS. Per poter utilizzare l’ampia letteratura disponibile viene dunque utilizzato un ambiente di sviluppo DJGPP il quale coniuga software OPESOURCE/FREEWARE con il S.O. Windows.

La architettura proposta è quella di un processore INTEL 386 o superiore (come vedremo non cambia molto) e dunque – rispetto alla architettura studiata in precedenza e valida per qualsiasi tipo di processore che sia stato realizzato seguendo il modello di VON NEUMANN – verranno definiti alcuni specifici registri.

(3)

Dispensa I.6 versione 1.0 mail: lamonica@associatesonline.it Pagina 3 di 20

LA FAMIGLIA CPU 8086

Tutte le CPU della famiglia Intel presentano alcune caratteristiche comuni, tra le quali il linguaggio macchina nativo

Le macchine 8088 (1979) ed 8086 (giugno 1978) risultano Identiche dal punto di vista della programmazione, sono dotate di 16 registri generali a 16 bit e possono gestire programmi di al massimo 1 megabyte di memoria.

Operano solo il REAL MODE, Non c’è alcuna limitazione sugli indirizzi di memoria cui un generico programma può accedere.

Il processore può indirizzare fino a 1 MEGABYTE di memoria ( indirizzo a 20 bit ).

Le macchina 80286 (1982) aggiunge nuove istruzioni in linguaggio macchina, inoltre permette di operare in PROTECTED MODE e compare il concetto di memoria virtuale, tuttavia i registri continuano ad essere a 16 bit

Le macchina 80386 (1985) estende i registri a 32 bit permettendo l’indirizzamento tramite 32 bit e dunque potendo allocare fino a 4 GB di dati ( 2 elevato alla 32).

Dalla macchina 80486 in poi non ci sono stati – a livello di architettura – grossi cambiamenti mentre sono state migliorati gli aspetti prestazionali dei processori sia tramite la aggiunta di istruzioni per la gestione delle immagini (MMX MultiMedia eXtensions) sia ottimizzando la gestione delle risorse della CPU (CACHE, gestione della predizione dei CACHE HIT/MISS, gestione del PIPELINING, etc etc)

(4)

Dispensa I.6 versione 1.0 mail: lamonica@associatesonline.it Pagina 4 di 20

MODALITA’ DI INDIRIZZAMENTO

La macchina 8086 permette di lavorare allocando fino ad 1 MB di memoria Centrale (e dunque è necessario un indirizzo di 20 bit), la macchina 80286 indirizza fino a 16 MB.

Essendo tali CPU dotate di registri da 16 bit l’indirizzamento avveniva utilizzando 2 registri (e dunque è possibile avere indirizzi fino a 32 bit).

L’indirizzo è dunque distinto in due componenti:

• Selettore, che indicava un insieme di locazioni di memoria chiamate SEGMENTO

• Offset, che indicava all’interno del segmento, la POSIZIONE (o spostamento dalla prima posizione)

Per ottenere l’indirizzo fisico dalla coppia segmento e posizione l’indirizzo fisico si calcola Indirizzo fisico = segmento * 161 + posizione

Ad esempio l’indirizzo fisico referenziato dalla coppia 0A12:0032 è 0A12*F + 0032 = A120+0032 = A152

1 Moltiplicare per 16 in esadecimale significa aggiungere uno 0 a destra del numero.

(5)

Dispensa I.6 versione 1.0 mail: lamonica@associatesonline.it Pagina 5 di 20

REAL MODE / PROTECTED MODE

• In modalità reale l’indirizzo (segmento:posizione) individua un indirizzo fisico della memoria centrale. Non vi è modo per un programma di limitare gli indirizzi a cui accedere.

• In modalità protetta a 16 bit invece viene introdotta la tecnica della memoria virtuale. I

segmenti sono spostai tra memoria centrale e disco all’occorrenza, tutto ciò in maniera trasparente rispetto al programma.

Dunque ad ogni segmento è associata una tabella in cui sono indicate una serie di informazioni(dove si trova il segmento, se è sul disco o nella memoria, permessi di accesso, etc etc). L’indice della riga associata al segmento è contenuta nel SELETTORE.

Nella modalità protetta a 16 bit il segmento è monolitico (o si trova nella memoria o nel disco)

• In modalità protetta a 32 bit, la posizione diviene un numero da 32 bit (e dunque i

segmenti passano da 64 kB (2 elevato alla 16) a 4.000.000 kB (2 elevato alla 32)

Nella modalità protetta a 32 bit il segmento NON è monolitico essendo divisibile in pagine da 4 kB (potendo trovarsi in parte sul disco in parte in memoria centrale).

(6)

Dispensa I.6 versione 1.0 mail: lamonica@associatesonline.it Pagina 6 di 20

LA MEMORIA

La memoria è divisa in una serie di locazioni indirizzabili.

Ogni locazione indirizzabile può essere più o meno “capiente” in dipendenza della tecnologia utilizzata.

Le meno recenti permettevano di contenere 1 Byte per locazione mentre adesso è possibile immagazzinare fino a 16 byte per locazione; tale ampliamento è stato seguito di pari passo dall’aumento del parallelismo del BUS di accesso.

Di seguito un esempio di memoria con capienza 1 Byte (1 B è 8 cifre binarie oppure 2 cifre HEX)

Sono dunque definite delle unità superiori al Byte

(7)

Dispensa I.6 versione 1.0 mail: lamonica@associatesonline.it Pagina 7 di 20

I REGISTRI

Oltre ai registri interni necessari al funzionamento del processore (vedi Dispensa I.3) non sempre visibili al programmatore sono presenti altri Registri Visibili ed Utilizzabili dal programmatore.

Tali registri si distinguono in REGISTRI GENERALI e REGISTRI SPECIALI e possono essere utilizzati dal programma per contenere dati da elaborare.

Registri generali sezionabili in 2 registri da 8 bit

(8)

Dispensa I.6 versione 1.0 mail: lamonica@associatesonline.it Pagina 8 di 20

(9)

Dispensa I.6 versione 1.0 mail: lamonica@associatesonline.it Pagina 9 di 20

CICLO DI SVILUPPO

Viene di seguito propposto il ciclo di sviluppo per la realizzazione di un programma (insieme di istruzioni) da far eseguire su un elaboratore.

L’insieme di istruzioni viene digitato in un file di testo tramite un editor (file sorgente).

Viene di seguito elaborato da un programma di assemblaggio che – previa verifica sintattica – lo

“traduce” in un file oggetto che viene di seguito connesso a librerie esistenti (linked) e dunque confezionato in un unico file eseguibile.

(10)

Dispensa I.6 versione 1.0 mail: lamonica@associatesonline.it Pagina 10 di 20

FORMATO DEL CODICE SORGENTE

Ogni linea di codice sorgente è costituita da 4 parti (o campi) LABEL / OPCODE / OPERANDS /COMMENTS

LABEL è una stringa alfanumerica che definisce un nome simbolico per il corrispondente indirizzo.

OPCODE è un codice mnemonico o pseudo-operatore e determina la generazione di un’istruzione in linguaggio macchina oppure la variazione del valore corrente del Program Counter

OPERANDS sono gli oggetti dell’azione specificata dall’OPCODE, e variano a seconda dell’OPCODE e del modo di indirizzamento.

COMMENTS è un testo arbitrario inserito dal programmatore.

Ad esempio

POSIZIONE: ADD AX,4 ; sommo 4 al valore presente nel registro AX

La label POSIZIONE permetterà al programmatore di individuare l’istruzione negli altri punti del programma e tornarci (ad es.) con una istruzione di salto

(11)

Dispensa I.6 versione 1.0 mail: lamonica@associatesonline.it Pagina 11 di 20

OPERANDI

Dipendentemente dal OPCODE il numero di operandi varia. Il tipo di operando può essere:

• REGISTRO: fa riferimento al contenuto di un registro

• MEMORIA: fa riferimento a dati in memoria

• IMMEDIATO: un valore costante espresso nella istruzione

• IMPLICITO: un valore deducibile dal OPCODE

(12)

Dispensa I.6 versione 1.0 mail: lamonica@associatesonline.it Pagina 12 di 20

ISTRUZIONE MOV

La sintassi corretta è

MOV destinazione , sorgente

I dati specificati in sorgente vengono spostati (copiati) in destinazione.

mov ax, 3A34 ; sposta il valore 3A34 nel registro ax

mov bx, ax ; sposta il valore contenuto nel registro ax nel registro bx

mov ax, [3A34] ;sposta il valore contenuto nella locazione di memoria referenziata dall’indirizzo 3A34 (offset) nel registro ax

mov [3A34] , ax ;sposta nella locazione di memoria referenziata dall’indirizzo 3A34 (offset) nel registro ax

(13)

Dispensa I.6 versione 1.0 mail: lamonica@associatesonline.it Pagina 13 di 20

ISTRUZIONE ADD

La sintassi corretta è

ADD operando1 , operando2

Lo scopo della istruzione ADD è permettere la somma di interi (il risultato viene salvato in operando1)

add ax, 3A34 ; somma il valore 3A34 al registro ax e salva il risultato in ax

add bx, ax ; somma il valore contenuto nel registro ax nel registro bx e salva il risultato in bx add ax, [3A34] ; somma il valore contenuto nella locazione di memoria referenziata

dall’indirizzo 3A34 (offset) al registro ax e salva il risultato in ax

(14)

Dispensa I.6 versione 1.0 mail: lamonica@associatesonline.it Pagina 14 di 20

ISTRUZIONI INC E DEC

La sintassi corretta è

INC operando1 DEC operando1

Lo scopo della istruzione INC è incrementare di una unità il valore contenuto nel registro indicato tramite

operando1

l

Lo scopo della istruzione DEC è incrementare di una unità il valore contenuto nel registro indicato tramite

operando1

l

(15)

Dispensa I.6 versione 1.0

DIRETTIVE

Le direttive non sono istruzioni bensì comandi dati al compilatore ASSEMBLER.

Usi comuni delle direttive sono:

definire costanti

definire memoria per memorizzare dati raggruppare memorie in segmenti etc etc

La direttiva EQU e DEFINE

ALTEZZA EQU 34

La label ALTEZZA assume il valore 34.

%define SIZE 100

La label SIZE assume il valore 100.

DIRETTIVE DATI

Le direttive D e RES servono per inizializzare riservare memoria.

mail: lamonica@associatesonline.it

direttive non sono istruzioni bensì comandi dati al compilatore ASSEMBLER.

definire memoria per memorizzare dati raggruppare memorie in segmenti

ALTEZZA assume il valore 34.

La label SIZE assume il valore 100.

direttive D e RES servono per inizializzare riservare memoria.

Pagina 15 di 20 direttive non sono istruzioni bensì comandi dati al compilatore ASSEMBLER.

(16)

Dispensa I.6 versione 1.0 mail: lamonica@associatesonline.it Pagina 16 di 20

DIRETTIVA RES

La direttiva DES viene utilizzata dal programmatore per individuare un “pezzo” di memoria entro il quale ha intenzione di conservarci un dato durante l’esecuzione del programma. D’ora in avanti parleremo di VARIABILE come di una o più locazioni di memoria destinate a contenere un dato.

Il programmatore avrà l’onere di stabilire quando grande (quanti byte) dovrà contenere la VARIABILE e questa informazione sarà essenziale al compilatore per definirne la grandezza.

Ad esempio supponiamo che il programmatore voglia individuare una variabile che conterrà un carattere. Come sappiamo la memoria può contenere solo numeri binari, e dunque ad ogni carattere viene associato un codice che può essere:

• ASCII (American Standard Code for Information Interchange) che individua fino a 256 diversi caratteri ( 2 elevato alla 8 quindi 1 BYTE)

• Unicode che estende a caratteri di tutte le lingue del mondo utilizzando 1 WORD (2 BYTE) Supponendo che il programmatore scelga il codice UNICODE, allora dovrà comunicare al programma che la variabile dovrà essere di 1 WORD.

pippo RESW 1 ;riserva 1 WORD e la indica con il nome pippo pluto RESB 10; riserva 10 BYTE e la indica con pluto

(17)

Dispensa I.6 versione 1.0 mail: lamonica@associatesonline.it Pagina 17 di 20 In generale la direttiva RES può riservare BYTE, WORD, DOUBLE WORD, QUAD WORD, TEN BYTE utilizzando le lettere B , W , D , Q , T

DIRETTIVA D

La direttiva D ha la medesima funzione di RES permettendo inoltre di inizializzare la variabile con un valore prestabilito (che potrà poi comunque cambiare durante la esecuzione del programma).

Ad esempio

pippo db ‘c’,’i’,’a’,’o’,0 ;definisce una variabile di 5 byte (4 byte contengono le lettere ciao + 1 byte che contiene uno 0 che fa da fine riga) pippo db “ciao”,0 ;identico a quanto sopra descritto

(18)

Dispensa I.6 versione 1.0 mail: lamonica@associatesonline.it Pagina 18 di 20

INPUT ED OUTPUT

Le attività di input (leggi i dati da tastiere) ed Output (scrivi i dati a video) sono estremamente complesse e – per quanto ci riguarda – utilizzeremo delle funzioni già esistenti che collegheremo ai nostri programmi.

In tale maniera non solo possiamo concentrarci su quella parte di codice che ci interessa ma iniziamo a comprendere una delle regole fondamentali dell’informatica :

“non si ricrea quello che già esiste, ma lo si utilizza”

In particolare utilizzeremo delle funzioni che andranno a leggere e scrivere sul registro EAX.

print_int stamperà a video il numero intero memorizzato nel registro EAX

print_char stamperà a video il carattere corrispondente al codice ASCII contenuto nel registro AL print_string stamperà a video la stringa contenuta in memoria all’indirizzo memorizzato in EAX (la stringa deve terminare con un null cioè 0)

print_nl stampa a video una nuova riga (cioè va “daccapo”)

read_int legge un numero intero dalla tastiera e lo memorizza nel registro EAX read_char legge un carattere dalla tastiera e lo memorizza nel registro EAX

Come vedremo le funzioni sopra descritte saranno eseguite utilizzando l’istruzione CALL

(19)

Dispensa I.6 versione 1.0 mail: lamonica@associatesonline.it Pagina 19 di 20

RAPPRESENTAZIONE DEGLI INTERI

Come abbiamo visto le CPU sono passate da registri a 8 bit a registri a 16, poi 32 ed infine, ultimamente a 64 bit.

Ciò nonostante nel tempo non sono state variate le grandezze (numero di byte) associati ad un determinato tipo di dato2.

Un numero intero è storicamente associato a 2 BYTE (16 bit) e quindi può contenere fino a 65535 valori diversi (2 elevato alla 16).

Se vogliamo associare ad una stringa di bit un numero positivo allora possiamo sicuramente utilizzare la notazione BINARIA a noi nota per rappresentarlo.

Ad esempio 152 diviene 10011000

Se dunque destiniamo 2 BYTE ad un numero intero sappiamo che possiamo rappresentare i numeri compresi tra 0 e 65535 (216 - 1).

Ma se vogliamo rappresentare un numero negativo – non avendo a disposizione nessun altro simbolo che non siano 0 ed 1 – dobbiamo sacrificare almeno un bit per rappresentare il segno.

La rappresentazione ATTUALMENTE utilizzata e il complemento a 2

Dato un numero binario si esegue il complemento ad 1 del numero (ogni 0 diviene 1 ed ogni uno diviene 0) ed a questo viene poi sommato 1

Ad esempio 23 in binario diviene 00010111. Per rappresentare -23 dobbiamo

• prima eseguire il complemento ad 1 di 23 che dunque diviene 11101000

• sommarci 1 e dunque diviene 11101001 dunque da 00010111 si passa a 11101001.

2 Con l’arrivo delle architetture a 64 bit effettivamente sono state raddoppiate le quantità di BYTE associate ad alcuni tipi di dato.

(20)

Dispensa I.6 versione 1.0 mail: lamonica@associatesonline.it Pagina 20 di 20

DECREMENTARE LA DIMENSIONE DI INTERI

Supponiamo di avere un intero insigned – cioè un intero che non può assumere valori negativi rappresentato con 16 bit. Possiamo sicuramente pensare di rappresentarlo con meno bit (ad esempio 8) se tutti i bit che non rappresentiamo sono 0.

Ad esempio 000000001111111 (255 in decimale) può essere rappresentato con 11111111 – e cioè tronchiamo 8 0 più a sinistra – senza avere alcuna perdita di informazione.

Nel caso in cui invece abbiamo un numero rappresentato con complemento a 2 (quindi un numero che può essere anche negativo) dobbiamo rispettare la seguente regola.

E’ possibile ridurre il numero di bit purchè

• tutti i bit eliminati siano dello stesso valore.

• il primo bit non rimosso sia dello stesso valore di quelli rimossi.

Ad esempio 1111111111101001 (- 23 rappresentato a 16 bit) può essere ridotto a 11101001 essendo eliminati TUTTI 1 ed essendo il bit più significativo (il primo non rimosso) ancora 1.

Riferimenti

Documenti correlati

Toscana Dab (operante sulla frequenza 11B) e Radio Digitale Toscana (operante sulla frequenza 11C) veicolano complessivamente i contenuti di 32 imprese radio- foniche locali

la Dgscerp del MiSe, a seguito della se- duta pubblica svoltasi nella medesima giornata ha pubblicato la determina relativa alla graduatoria dei soggetti utilmente

I 250mila euro messi a disposizione delle emittenti locali lombarde (altri 250mila euro sono destinati alle testate giornalistiche locali) sono specificamente destinati

li, tutte facenti parte del sistema associativo AERANTI-CORALLO) e Adria Dab Marche (partecipata da emittenti radiofoniche locali, in maggioranza facenti parte del

■ La Dgscerp del Ministero dello Sviluppo economico, ha pubblicato nel sito istituzio- nale del Ministero stesso il nuovo decreto direttoriale 8 giugno 2021 con il

E’, pertanto, necessario, a parere di AERANTI-CORALLO, tenere conto di tali aspetti tecnici nel disciplinare le selezioni dei Fsma, al fi- ne di evitare un

■ Mentre non sono stati ancora completati i procedimenti per l’assegnazione nella maggior parte delle aree tecniche dei nuovi diritti di uso per la diffusio- ne dei contenuti locali

• Il trattamento, se effettuato in post emergenza della coltura, deve essere eseguito con mais in buono stato vegetativo: non applicare il prodotto su colture danneggiate da