laboratorio di architettura degli elaboratori …unina.stidue.net/calcolatori elettronici...

113
LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA Scheda basata su processore Intel PXA255 Descrizione del sistema UNI-PD-PXA ed esercizi

Upload: doankien

Post on 18-Feb-2019

220 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

Scheda basata su processore Intel PXA255

Descrizione del sistema UNI-PD-PXA ed esercizi

Page 2: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

2

Indice

Introduzione 5 CAPITOLO I Architettura ARM e architettura Xscale 7 Nota storica 7 1.1 Il consorzio ARM 8 1.2 L’architettura ARM 8 1.3 L’architettura Intel Xscale 11 1.4 Caratteristiche principali del core Xscale 13 CAPITOLO II Il chip Intel PXA255 15

2.1 Il PXA255 – “System on chip” 15 2.2 Il PXA255 – Il memory controller 16 2.3 Il PXA255 – I clock e la gestione dell’alimentazione 16 2.4 Il PXA255 – Il modulo universal serial bus client (USB) 17 2.5 Il PXA255 – Il controller DMA (DMAC) 17 2.6 Il PXA255 – Il controller LCD 17 2.7 Il PXA255 – Il controller AC97 17 2.8 Il PXA255 – Il controller Inter-IC Sound (I2S) 18 2.9 Il PXA255 – Il controller Multimedia Card (MMC) 18 2.10 Il PXA255 – La porta a infrarossi (Fast Infra Red - FIR) 18 2.11 Il PXA255 – Il controller ‘Synchronous Serial Protocol’ (SSPC) 18 2.12 Il PXA255 – L’interfaccia Inter Integrated Circuit (I2C) 18 2.13 Il PXA255 – I pin General Purpose I/O (GPIO) 19 2.14 Il PXA255 – Le porte UART 19 2.15 Il PXA255 – La porta Full Function UART (FFUART) 19 2.16 Il PXA255 – La porta Bluetooth UART (BTUART) 19 2.17 Il PXA255 – La porta standard UART (STUART) 19 2.18 Il PXA255 – La porta hardware UART (HWUART) 19 2.19 Il PXA255 – Il Real Time Clock (RTC) 20 2.20 Il PXA255 – Gli OS timer 20 2.21 Il PXA255 – Il Pulse Width Modulator (PWM) 20 2.22 Il PXA255 – L’Interrupt control 20 2.23 Il PXA255 – La porta Synchronous Serial Protocol (SSP) 20

Page 3: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

3

CAPITOLO III La Scheda UNI-PD-PXA 21 3.1 L’architettura della scheda 23 3.2 Connessioni e preparazione della scheda al power on 23 3.3 Power on 23 3.4 La memoria residente on board 24 3.5 Il CODEC audio UCB1400 25 3.6 La Compact Flash 25 3.7 La Multimedia Card 25 3.8 Le porte seriali 26 3.9 I connettori di espansione (J6, J7) 27 3.10 L’interfaccia LCD 27 CAPITOLO IV L’Ambiente di sviluppo su PC 29 4.1 L’ambiente di sviluppo del software 30 4.2 Gli strumenti di sviluppo del software 30 4.3 Interazione con il target e fase di debug del codice sviluppato 43 CAPITOLO V Esercizi 53 5.1 Primo programma (somma di due numeri) 53 5.2 Secondo programma (somma di due numeri) 56 5.3 Terzo programma (somma di due numeri) 58 5.4 Somma degli elementi di un vettore 60 5.5 Somma degli elementi di un vettore (subroutine) 62 5.6 Somma degli elementi di un vettore (subroutine ricorsiva) 65 5.7 Rovesciamento di una stringa di caratteri 68 5.8 Rovesciamento di una stringa di caratteri (con sp allineato) 71 5.9 Ordinamento di un vettore (merge-sort) 73 5.10 Il pannello frontale: i led e gli switch 77 5.11 Il pannello frontale: i pulsanti 80 5.12 Il display LCD 83 5.12.1 Disegnare a 16 colori 84 5.12.2 Disegnare a 256 colori 87 5.12.3 Scrivere caratteri sul display 89 5.13 Libreria per l’uso del display LCD 95

Page 4: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

4

BIBLIOGRAFIA 111 APPENDICE: Mappa di memoria, layout e schemi elettrici della scheda 113

Page 5: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

5

Introduzione

Questo testo intende fornire al lettore le conoscenze di base per poter operare in completa autonomia su una stazione di sviluppo in cui il target è costituito da una scheda basata su processore Intel PXA255 connessa ad un host computer tramite un link seriale RS232 in ambiente GDB.

Si esamineranno le varie parti costituenti la stazione di sviluppo dando ovviamente maggiore enfasi al target, ma senza trascurare i vari ambienti software su cui ci si basa per la scrittura e il debug dei vari programmi.

Dopo aver fornito le informazioni di base necessarie, relative alle diverse parti, si prenderanno in esame alcuni esempi di cui, oltre a fornire la descrizione, si analizzerà il codice (normalmente scritto in linguaggio assembly) e si descriveranno le operazioni di download sul target e di debug.

Si ritiene utile iniziare presentando una figura rappresentativa della stazione di svi-luppo. Nei capitoli successivi si identificheranno e analizzeranno le varie parti compo-nenti la stazione.

Poiché questo intende essere un manuale d’uso di una scheda basata su core ARM, piuttosto che una descrizione tecnica dei suoi componenti, il livello di dettaglio della descrizione sarà inevitabilmente tale da richiedere a volte approfondimenti da effet-tuare su testi di cui si forniranno le indicazioni bibliografiche.

Anche se la suddivisione del testo è stata fatta in 5 capitoli, gli obiettivi sono essen-zialmente due: - il primo obiettivo (cap. I, II, III) è acquisire familiarità con la stazione di lavoro

(PC + scheda UNI-PD-PXA) e con l’ambiente di sviluppo (GNU – GDB); - il secondo obiettivo (cap. IV e V) è di guidare il lettore nell’uso in laboratorio della

scheda UNI-PD-PXA, fornendo sia le informazioni relative agli strumenti software da utilizzare, sia alcuni esempi da collaudare.

Page 6: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

6

Stazione di Lavoro Il sistema è composto da:

• PC di mercato con Windows 98/2000/XT

• Scheda UNI-PD_PXA • Alimentatore ac/dc per la

scheda (non visualizzato)

Vista posteriore PC Connessioni PC:

• Cavo Jtag per programmazione • Cavo Rs232 per programmazione e

debug • Cavo di alimentazione AC • Cavi per mouse, keyboard e CRT

Vista posteriore UNI-PD-PXA Connessioni PC:

• Cavo Rs232 per pro-grammazione e debug

• Alimentazione 9V DC Porte disponibili:

• USB tipo B • RS232 • RS485

Eliminato:

Page 7: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

7

CAPITOLO I

Architettura ARM e architettura Xscale

Nota storica

Il core Xscale è il primo RISC ARM nato in casa Intel.

Il primo RISC in assoluto è nato nel 1985 dalla ACORN Computer Group. Nel 1997 il RISC della ACORN debutta come primo processore RISC utilizzato in computer a basso costo. Il termine RISC sta per ‘Reduced Instruction Set Computer’. Nelle mac-chine RISC ogni istruzione viene decodificata per pilotare direttamente le risorse hardware e mediamente ogni istruzione viene eseguita in un solo ciclo di clock.

Nel novembre 1990 viene costituito il consorzio ‘ADVANCED RISC MACHINES’ (ARMTM) dalla APPLE, ACORN e VLSI technology. Nel 1991 la ARM introduce il suo primo core RISC embedded: l’ARM6.

Gli obiettivi di ARM sono le prestazioni elevate, l’alta integrazione ed il basso consumo dei componenti.

Nel 1998 la Intel acquisisce la Digital Equipment Corporation, ereditando così la tec-nologia StrongarmTM ideata dalla Digital successivamente ad un accordo con la ARM, dalla quale aveva ottenuto il permesso di modificare il core ARM mantenendone la compatibilità software.

Il core Xscale è il primo core ARM completamente disegnato ed ottimizzato dalla In-tel in tecnologia .18μm. Basate su questo core, la Intel ad oggi ha realizzato oltre quattordici famiglie di prodotti diversi, ognuna delle quali è stata pensata per una fa-scia diversa del mercato. Il componente che è alla base del target descritto in questo manuale è uno di questi quattordici ed è siglato PXA255.

Eliminato: costituiti

Page 8: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

8

1.1 Il consorzio ARM

Il consorzio ARM progetta sistemi e microprocessori innovativi che poi fornisce alle maggiori compagnie mondiali del settore, che a loro volta le implementano nel proprio silicio.

La architettura ARM negli anni ha monopolizzato il mercato giungendo, nel 2001, a co-prire oltre il 75% delle applicazioni RISC a 32 bit.

1.2 L’architettura ARM

Il set di istruzioni della architettura ARM è evoluto significativamente da quando è stato introdotto la prima volta e continuerà ad evolvere in futuro.

Si sono succedute negli anni 5 versioni del set di istruzioni, denotate da un numero in-crementale da 1 a 5.

Oltre al numero della versione, a volte si evidenziano delle lettere aggiuntive che indi-cano la presenza di altre istruzioni addizionali.

Le 5 versioni del set di istruzioni della architettura ARM sono:

Versione 1: Questa versione non è mai stata usata in prodotti commerciali. Essa con-tiene:

• Le istruzioni di base (non include la moltiplicazione) • Istruzioni di lettura e scrittura per byte, word e multi-word • Istruzioni di salto • Istruzione di interrupt software

La prima versione del set di istruzioni ARM aveva indirizzi da 26 bit.

Versione 2: Con questa versione si sono avute le seguenti estensioni: • Istruzioni di moltiplicazione e di moltiplicazione con accumulo • Supporto per coprocessore • Due registri extra per il fast interrupt mode • Istruzioni atomiche (indivisibili) di lettura-scrittura, chiamate SWP e SWPB

Anche la versione 2 e 2a avevano indirizzi da 26 bit.

Le versioni fino alla 2 sono oggi obsolete.

Versione 3: Con questa versione gli indirizzi sono da 32 bit e, di conseguenza, lo spa-zio di indirizzamento è stato esteso a 4GByte. Le informazioni di stato che preceden-temente venivano memorizzate nel registro R15 sono state spostate su un nuovo regi-stro ‘Current Program Status Register’ (CPSR) e sui ‘Saved Program Status Register’ (SPSR), che sono stati introdotti per preservare il contenuto di CPSR quando si veri-

Page 9: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

9

fica una eccezione. Ne consegue che con la versione 3 si è avuto il seguente cambia-mento:

• Sono state introdotte due nuove istruzioni (MRS e MSR) per permettere l’accesso a CPSR e agli SPSR

La versione 3 include anche due nuovi modi di operare, necessari a rendere possibile l’uso delle eccezioni di data abort, prefetch abort e undefined instruction diretta-mente dal sistema operativo.

Versione 4: Con questa versione sono state create le seguenti estensioni: • Istruzioni di lettura e scrittura di halfword (16 bit) • Istruzioni di lettura con estensione del segno, di byte e halfword • Nella versione T è stata introdotta una istruzione necessaria al trasferimento

in thumb mode • Un nuovo modo privilegiato che usa i registri del modo user

Versione 5: Con questa versione sono state create le seguenti estensioni: • E’ stato migliorato il passaggio dal modo normale al modo thumb • Consente l’uso delle stesse tecniche di generazione del codice sia nella modalità

thumb che nella modalità non thumb • E’ stato introdotta una istruzione di breakpoint software • Sono state introdotte più opzioni per l’uso di coprocessori

Oltre alle precedenti versioni, sono stati introdotte anche delle varianti (di volta in volta indicate con delle lettere).

Il set di istruzioni Thumb (variante T): Il set di istruzioni thumb è un subset del set di istruzioni ARM. Le istruzioni thumb hanno una dimensione che è pari alla metà della dimensione delle istruzioni ARM (16 bit invece che 32). Il risultato che ne deriva è che normalmente può essere ottenuta una maggiore densità di codice utilizzando il set Thumb invece che il set ARM.

Utilizzando il set di istruzioni Thumb si hanno due limitazioni:

• Per la realizzazione della stessa funzione, il codice thumb usa più istruzioni del codice ARM e quindi il codice ARM è meglio indicato per massimizzare le pre-stazioni di un codice con criticità di tempi di esecuzione.

• Il set di istruzioni Thumb non include alcune istruzioni necessarie per la gestio-ne delle eccezioni.

La presenza del set di istruzioni Thumb è denotata dalla lettera T (non si applica alle versioni antecedenti alla versione 4).

Istruzioni di moltiplicazione con risultato a 64 bit (variante M): La variante M al set di istruzioni ARM include 4 istruzioni che realizzano le operazioni 32x32 64 e 32x32 + 64 64 con accumulo. La presenza di queste istruzioni è denotata dalla let-tera M.

Page 10: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

10

La prima introduzione di queste istruzioni si è vista a partire dalla versione 3 del set di istruzioni ARM.

Istruzioni DSP (variante E): La variante E del set di istruzioni ARM include un nume-ro di istruzioni extra che migliorano le prestazioni del processore ARM, tipicamente in applicazioni di digital signal processing.

Fig. 1.1 – Sommario delle architetture ARM

Page 11: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

11

1.3 L’architettura Intel XScale

L’architettura Intel Xscale è compatibile con il core ARM v5TE. Basate su questo core, esistono oggi diverse famiglie di prodotti Intel, come mostra la seguente figu-ra:

Fig 1.2 - Prodotti Intel Xscale

Le caratteristiche principali di questo core possono essere così elencate: • Tecnologia Intel pipelined RISC • 32Kbyte di cache istruzioni, 32 Kbyte di cache dati e 2 Kbyte di mini-data

cache • Tecnologia Intel ‘Media Processing’ • Tecnologia Intel wireless MMX • Memory management unit dedicata (MMU) • Monitoraggio delle prestazioni interno al core • Power management e clock control unit interne al core • Connessione full JTAG • Istruzioni SIMD per l’elaborazione di dati multimediali • Traslazioni veloci dagli indirizzi logici a quelli fisici con controllo della cache • Miglior rapporto prestazioni/consumo grazie alle varie modalità di funzionamen-

to con low power ottimizzato

Page 12: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

12

Fig. 1.3 – Schema a blocchi del core Xscale

Fig. 1.4 – Rapporto Mips per Watt del core Xscale

Page 13: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

13

1.4 Caratteristiche principali del core Xscale

Come già accennato, il core Xscale è compatibile ARM v5TE e può operare in uno fra sette modi diversi: User, System, Supervisor, Abort, Undefined instruction, Fast In-terrupt e Normal Interrupt. Esso comprende 16 registri a 32 bit (R0..R15), di cui R13 è lo stack pointer, R14 il link register e R15 il program counter.

Supporta sia la rappresentazione big endian che la rappresentazione little endian (nel-la versione del core integrata nel PXA255 è stata eliminata la rappresentazione big endian). Il passaggio dall’una all’altra modalità di funzionamento è determinato impo-stando il bit B del Control Register (Coprocessore 15, registro 1, bit 7). Lo stato di default al power on è little endian.

Rispetto allo standard ARM v5TE, il core Xscale implementa delle estensioni: • E’ stato aggiunto un coprocessore DSP (CP0) che contiene un accumulatore a 40

bit e 8 nuove operazioni nello spazio coprocessore. • Sono state aggiunte delle funzionalità al coprocessore 15 ed è stato creato il

coprocessore 14.

Ulteriori dettagli sulla architettura Xscale, nonché sul suo set di istruzioni aggiunte, possono essere trovati nel documento Intel 278525-001.pdf, che può essere scaricato direttamente dal sito Intel.

Page 14: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

14

Page 15: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

15

CAPITOLO II

Il chip Intel PXA255

2.1 Il PXA255 – “System on chip”

Lo scopo di questo capitolo è di fornire una breve descrizione di tutti i moduli pre-senti all’interno del PXA255. Per approfondimenti maggiori ci si può riferire ai do-cumenti Intel 278796.pdf e 278693.pdf, direttamente scaricabili dal sito.

Fra i vari componenti basati su core Xscale, uno dei più diffusi è sicuramente il PXA255.

Il PXA255 può essere definito un ‘sytem on chip’ che integra un elevato numero di periferiche grazie alle quali risulta particolarmente adatto all’uso nel settore dei cosiddetti ‘handheld devices’: palmari, telefoni cellulari e applicazioni portatili lo-wpower.

Fig. 2.1 – Architettura interna del PXA255

Page 16: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

16

Come indicato in figura 2.1, l’architettura interna del PXA255, basato su core Xscale, integra i seguenti componenti:

• Memory controller • Clock e gestione dell’alimentazione • Universal serial bus client (USB) • DMA controller • LCD controller • Interfaccia AC97 • Interfaccia I2S (Inter IC Sound) • Interfaccia MMC (Multimedia Card) • Interfaccia FIR (Fast Infra Red) • Interfaccia seriale sincrona • Interfaccia I2C (Inter Integrated Circuit) • General purpouse I/O • 4 UARTs • Real Time Clock • OS timers • PWM (Pulse Width Modulation) • Interrupt control

2.2 Il PXA255 – Il memory controller

Il memory controller interno al PXA255 fornisce tutti i segnali di controllo (senza alcun bisogno di elettronica aggiuntiva) per la gestione della maggior parte delle memorie esterne che ad esso si volessero interfacciare. Tutti i timing sui bus sono programmabili al fine di meglio adattarli alle varie esigenze esterne. Esso supporta fino a 4 banchi di SDRAM. Sono presenti anche 6 segna-li di chip select statici per interfacciare SRAM, SSRAM, Flash, ROM, SROM e companion chip. Supporta anche due slot PCMCIA o, in alternativa, due slot per compact flash.

2.3 Il PXA255 – I clock e la gestione dell’alimentazione

Tutti i blocchi interni al PXA255 sono pilotati dai clock derivati da un cristallo di 3.6864 MHz e da un cristallo opzionale da 32.768 kHz.

Il cristallo da 3.6864 MHz pilota un PLL centrale ed uno periferico. Lo scopo di equesti due PLL è di generare le frequenze necessarie ai vari blocchi interni.

Il cristallo da 32.768 kHZ fornisce una sorgente di clock esterna che deve es-sere abilitata dopo un reset hardware. Questo clock pilota un RTC interno, la power control unit e l’interrupt controller.

Page 17: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

17

Il cristallo da 32.768 kHZ è collegato ad una alimentazione separata, al fine di garantire il clock attivo in condizioni di sleep mode della CPU.

Il modulo di gestione dell’alimentazione (power management) controlla la transi-zione tra le modalità turbo, normale, idle e sleep.

2.4 Il PXA255 – Il modulo universal serial bus client (USB)

Il modulo USB client è basato sulla specifica dello standard USB revisione 1.1.

Esso supporta fino a 6 connessioni endpoint e fornisce una frequenza da 48MHz generata internamente.

Il controller USB implementa code FIFO con accesso in modalità DMA da e per la memoria.

2.5 Il PXA255 – Il controller DMA (DMAC)

Il DMAC fornisce 16 canali per il servizio di richieste di trasferimento dati da e per periferiche e fino a due richieste di trasferimento dati da companion chip esterni.

Esso opera in flow-through mode quando realizza trasferimenti da periferiche a memoria, da memoria a memoria e da memoria a periferiche. E’ compatibile con periferiche che usano trasferimenti a word, halfword e byte.

2.6 Il PXA255 – Il controller LCD

Il controller LCD supporta sia LCD passivi (DSTN) che attivi (TFT) con un mas-simo di risoluzione di 640x480 con una profondità di 16 bit di colori.

Esso ha due canali DMA dedicati per supportare sia single che dual panel display. Il modo passivo monocromatico supporta fino a 256 livelli di grigio men-tre il modo passivo a colori supporta fino a 65536 colori. Il modo attivo ne sup-porta fino a 65536.

2.7 Il PXA255 – Il controller AC97

Il controller AC97 supporta i CODEC in revisione 2.0. Questi CODEC possono operare fino ad una frequenza di campionamento di 48KHz. Il controller forni-sce 16 canali indipendenti per PCM stereo in, PCM stereo out, Modem in, Modem out e microfono mono. Ogni canale include una FIFO che supporta accessi in modalità DMA alla memoria.

Page 18: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

18

2.8 Il PXA255 – Il controller Inter-IC Sound (I2S)

Il controller I2S fornisce un collegamento seriale a CODEC standard per suono digitale stereo. Esso supporta sia I2S in formato normale che I2S in formato MSB-giustificato e fornisce 4 segnali per connessioni a un CODEC I2S.

I segnali del controller I2S sono multiplexati con i pin del controller AC97. Il controller include una FIFO che supporta accessi in memoria in modalità DMA.

2.9 Il PXA255 – Il controller Multimedia Card (MMC)

Il controller MMC fornisce una interfaccia seriale per memory card standard. Esso supporta fino a due card in MMC o in SPI mode con un transfer rate fino a 20 Mbps. Anche il controller MMC ha una FIFO che supporta accessi in memo-ria in modalità DMA.

2.10 Il PXA255 – La porta a infrarossi (Fast Infra Red - FIR)

La porta di comunicazione FIR è basata sullo standard ‘4 Mbps Infrared Data association (IrDA) Specification’. Essa opera in half duplex ed ha una FIFO per accessi in memoria in modalità DMA. La porta di comunicazione FIR usa i pin di trasmissione e ricezione della porta STUART per la connessione ai transceiver IrDA.

2.11 Il PXA255 – Il controller ‘Synchronous Serial Protocol’ (SSPC)

Il controller SSP implementa una interfaccia seriale sincrona che può operare fino ad un transfer rate di 1.84MHz a partire da 7.2kHz.

Essa supporta i seguenti standard: • National Semiconductor’s Microwire • Texas Instruments Synchronous Serial Protocol • Motorola’s Serial Peripheral Interface

Anche il controller SSPC ha una FIFO che supporta accessi in memoria in moda-lità DMA.

2.12 Il PXA255 – L’interfaccia Inter Integrated Circuit (I2C)

L’interfaccia I2C fornisce una connessione a due pin. Essa usa il primo pin per i dati e gli indirizzi ed il secondo pin per il clock.

Page 19: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

19

2.13 Il PXA255 – I pin General Purpose I/O (GPIO)

Ogni pin GPIO (General Purpose I/O) può essere programmato come uscita o come ingresso. Gli input possono generare interrupt programmabili sul fronte di salita o sul fronte di discesa. I GPIO primari non sono condivisi con altre peri-feriche mentre i GPIO secondari hanno una funzione alternativa che può essere rimappata verso le periferiche.

2.14 Il PXA255 – Le porte UART

Il PXA255 integra 3 porte UART. Ogni porta UART può essere usata come slow infrared port (SIR).

2.15 Il PXA255 – La porta Full Function UART (FFUART)

Il baud rate della porta FFUART è programmabile fino a 230 Kbps. Essa integra il set completo di pin per il controllo del modem.: nCTS, nRTS,nDSR, nDTR, nRI e nDCD. Anche questa porta ha una FIFO per accessi in modalità DMA in memo-ria.

2.16 Il PXA255 – La porta Bluetooth UART (BTUART)

Il baud rate della porta BTUART è programmabile fino a 921Kbps. La porta BTUART integra un set parziale di pin per il controllo di un modem: nCTS e nRTS. Gli altri pin di controllo di una eventuale porta modem possono essere im-plementati attraverso pin GPIO. Anche questa porta ha una FIFO per accessi in modalità DMA in memoria.

2.17 Il PXA255 – La porta standard UART (STUART)

Il baud rate della porta standard STUART è programmabile fino a 230Kbps. Questa porta non ha nessun pin di controllo per modem. Essi possono essere im-plementati tutti attraverso dei general purpouse I/O. Anche questa porta ha una FIFO per accessi in modalità DMA in memoria.

2.18 Il PXA255 – La porta hardware UART (HWUART)

Il PXA255 ha anche una porta UART con controllo di flusso hardware. Questa porta ha un set parziale di pin di controllo modem: nCTS e nRTS. Attraverso questi pin di controllo c’è la possibilità di fornire un ‘full hardware control’. Il baud rate di questa porta è programmabile fino a 921.6 Kbps. I pin di questa porta sono multiplexati con alcuni pin di controllo della PCMCIA. Per questa ra-

Page 20: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

20

gione la porta HWUART opera alla stessa tensione del bus. Inoltre, poiché il pin nPWE della porta PCMCIA è usato per la realizzazione dell’I/O a latenza varia-bile (VLIO), se questo pin si usa per la porta HWUART, VLIO non è utilizzabile.

2.19 Il PXA255 – Il Real Time Clock (RTC)

Il real time clock può essere agganciato ad entrambi i cristalli di quarzo.

Comandando il real time clock con il quarzo da 32.768 kHz, si ha un minor con-sumo durante la modalità sleep mode. Comandando il real time clock con il quar-zo da 3.68 Mhz si perde questo vantaggio ma si usa un solo quarzo invece di due. L’RTC fornisce una frequenza d’uscita costante a cui è associato un registro di allarme programmabile. Questo registro può essere utilizzato per ‘risvegliare’ il processore dallo sleep mode.

2.20 Il PXA255 – Gli OS timer

Gli OS timer possono essere utilizzati per realizzare un contatore con frequen-za di ingresso di 3.68 MHz a cui sono associati 4 registri di comparazione. Que-sti ultimi possono essere configurati per generare interrupt. Uno di loro può es-sere utilizzato anche per la realizzazione di un watch dog hardware.

2.21 Il PXA255 – Il Pulse Width Modulator (PWM)

Il PWM ha due uscite indipendenti che possono essere programmate per pilota-re due GPIO. Sia la frequenza che il duty cycle possono essere programmati in-dipendentemente. Ad esempio, uno può essere utilizzato per il controllo del contrasto dell’LCD e l’altro per il controllo della luminosità.

2.22 Il PXA255 – L’Interrupt control

Il controllore degli interrupt dirige gli interrupt del processore agli ingressi IRQ e FIQ. La maschera degli interrupt abilita o disabilita individualmente le sorgenti di interrupt.

2.23 Il PXA255 – La porta Synchronous Serial Protocol (SSP)

Il PXA255 ha una porta SSP ottimizzata per connessioni ad altri network A-SICs. E’ quindi possibile mandare il pin TX in alta impedenza e controllare la di-rezione dello stesso facendolo passare dalla funzione TX alla funzione RX.

Questa porta non è multiplexata con altre periferiche.

Page 21: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

21

CAPITOLO III

La scheda UNI-PD-PXA

La scheda UNI-PD-PXA è stata ideata e progettata con lo scopo di rendere di-sponibile, presso i laboratori didattici del Dipartimento di Ingegneria dell’Informazione dell’Università di Padova, un target basato su un core RISC all’avanguardia e di grande diffusione nei sistemi embedded: il core ARM. Il componente scelto è il PXA255 che, oltre ad integrare il più moderno core ARM oggi disponibile (XScale), presenta un elevato numero di interfacce interne per dispositivi periferici che lo rendono particolarmente adatto ad un ambiente di-dattico, perché consente di realizzare applicazioni sui più diffusi dispositivi di-gitali oggi disponibili: controller LCD, PCMCIA, AC97, USB, seriali sincrone, I2C bus ecc.

Al fine di consentirne un facile uso in laboratorio, la scheda è stata inserita in un box e munita di alcune interfacce e di alcuni dispositivi che possono essere utili allo studente nella realizzazione sia di piccoli esempi che di eventuali appli-cazioni più complesse: display LCD STN 320x240 con 16 bit di profondità di co-lore, 16 microswitch mappati in memoria e direttamente utilizzabili, 16 LED, 2 pulsanti direttamente connessi a dei pin general purpouse I/O, un CODEC audio, una interfaccia per schede compact flash, 4 porte seriali, un USB client, due connettori a cui si può accedere rimovendo il coperchio in plexiglas presente sul box e ai quali afferiscono tutti i segnali di bus del PXA255, nonché i segnali del-le interfacce che non sono state rese direttamente disponibili all’esterno del box.

La seguente figura presenta una immagine della scheda. Nei paragrafi successi-vi se ne descriveranno le varie parti.

Page 22: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

22

Page 23: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

23

3.1 L’architettura della scheda

Da come appare dallo schema a blocchi, il cuore di tutta la scheda è il PXA255. Va no-tato che tutta l’elettronica esistente esternamente al PXA255 è ‘passiva’ (non richie-de alcuna configurazione) ad eccezione del CODEC audio UCB1400.

3.2 Connessioni e preparazione della scheda al power on

Per alimentare la scheda, bisogna individuare il connettore di alimentazione posto sul retro del box. A questo connettore deve pervenire una tensione continua nel range 7.5V-15V e con il positivo interno.

Nota tecnica: Qualora venissero utilizzati alimentatori diversi da quelli forniti in dota-zione, si suggerisce di verificare che non abbiano un eccessivo ripple di tensione (0.4V max) e che siano in grado di erogare una corrente continua di circa 1.5 A.

3.3 Power on

Una volta predisposto quanto descritto al punto 3.2, si è pronti ad accendere la sche-da agendo sull’apposito interruttore. Si descrive ora sinteticamente quanto avviene subito dopo aver dato alimentazione.

• Portando l’interruttore sulla posizione ‘on’, partendo da una tensione in ingresso che può variare nel range 7.5V-15V, si alimenta la scheda secondo le temporiz-

CONTROL REG

LED

FF/BUS

MMC/BUS

SSP/BUS

USB/BUS

485 XCEIVER

(2X) 232 XCEIVER

DATA BUS

ADD BUS

AC97

BT/BUS

LCD BUS J LCD

J JTAG

PXA 255

1 J 232

J 485

J SD CARD

CODEC

SD CARD LDO-REG

J SPEAKER

J AUDIO OUT

SD RAM

FLASH

FLASH

374

J USB B

244

245

J CF

SD RAM

3V3

VCORE

RESET SWITCH

BUS L

BUS H

J PWR IN

J TOUCH

VCC

J AUDIO IN

244

245

J EXT

J DIP SWITCH

2 J 232

CODEC LDO-REG

CF LDO-REG

J RADIO

SRAM

SRAM

IR/BUS J IRDA

AUDIO AMPL

J MIC IN

J INVERTER

J BATT J DIP

SW

ITC

H

245

374

DIP SW

SCHEDA IO

Page 24: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

24

zazioni richieste dai dispositivi afferenti alle varie sezioni di alimentazione (5V, 3.3V e 1.4V). Si può prendere visione della avvenuta accensione, verificando che il led verde posto sul frontale sia acceso.

• Al power on, dopo il fronte di salita del segnale di reset, viene iniziata l’esecuzione della istruzione situata all’indirizzo 0 di memoria. A questo stesso indirizzo è mappato il segnale chip select CS0, per cui l’accesso all’indirizzo 0 da parte del processore (per il fetch della istruzione da eseguire) ha anche l’effetto di attivare il segnale select CS0. Questo segnale gestisce le memorie flash e, tramite le impostazioni dei jumper JP2, JP3 e JP4, il PXA255, al reset, viene informato sul tipo di flash utilizzate (16 bit, 32 bit, asincrone, sincrone, ecc.). In questa fase non è ancora disponibile alcun tipo di RAM e quindi non si possono utilizzare istruzioni che ad esempio dovessero fare uso dello stack pointer. La scheda può essere riportata in questo stato o spegnendola o agendo sul pulsante di reset. Per evitare reset accidentali, questo pulsante è interno e va raggiunto con una punta (ad esempio la punta di una matita).

• Secondo quanto dettato dallo standard ARM, l’indirizzo zero contiene l’istruzione di salto all’entry point del programma di inizializzazione dei vari di-spositivi interni ed esterni al PXA255, il quale deve provvedere poi a passare il controllo della CPU all’eventuale sistema operativo o, come nel caso delle schede UNI-PD-PXA presenti in laboratorio, al monitor ‘REDBOOT’ di cui si analizze-ranno in seguito le caratteristiche.

3.4 La memoria residente on board

La memoria con cui è stata equipaggiata la scheda è costituita da 32Mbyte di strata-flash organizzata per 32 bit, 64Mbyte di SDRAM organizzata per 32 bit e 512Kbyte di SRAM organizzata per 32 bit.

La RAM statica è stata gestita attraverso il chip select CS1 e può essere tenuta sotto tampone collegando il jumper J1 ad una batteria nel range (2.9V..3.6V).

Al power-on l’unica memoria disponibile è la flash, in quanto per poter utilizzare sia la SDRAM che la SRAM è necessario eseguire prima (su memoria flash) il codice che provvede ad effettuare tutte le impostazioni necessarie per definire le modalità (programmabili) di accesso del processore alle memorie e ai dispositivi interni al PXA255. Per gli scopi di questo manuale è sufficiente sapere che attualmente, sulle stazioni installate, le memorie e tutti gli altri dispositivi vengono impostati dal monitor Redboot che li rende immediatamente utilizzabili, anche se non agli indirizzi fisici ma a quelli virtuali dettati dalla table vector della MMU:

FLASH: 0x50000000..0x51FFFFFF (32MB) SDRAM: 0x00000000..0x03FFFFFF (64MB) SRAM: 0x06000000..0x0607FFFF (512KB)

Page 25: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

25

Per quanto riguarda la SDRAM va considerato che, pur essendo eseguito su memoria flash, il monitor Redboot ne fa uso di una piccola sezione e quindi si consiglia all’utente di collocare i propri programmi nella regione (situata al di sopra del primo MB di SDRAM), compresa tra i seguenti indirizzi:

0x00100000..0x03FFFFFF

3.5 Il CODEC audio UCB1400

L’UCB1400 è un CODEC audio stereo equipaggiato con un touch screen. L’interfaccia verso la CPU è standard AC97 Rev. 2.1. Il suo ingresso stereo può essere connesso di-rettamente ad un microfono o ad un lettore CD. Sulla scheda UNI-PD-PXA l’ingresso è stato direttamente collegato al connettore presente sul frontale. L’uscita può pilotare una cuffia ma nel nostro caso è stato interposto un amplificatore audio del tipo LM4881MM ed è stato inserito nel box scheda un piccolo altoparlante (mono). Oltre al touch screen a 4 fili di tipo resistivo è anche presente un convertitore analogico di-gitale a 10 bit del tipo ad approssimazioni successive. La versione attuale del firmware presente sulle schede UNI-PD-PXA non integra il driver di questo componente per cui il lettore non ne può far uso per esercizi a meno che non lo configuri preventivamente. Coloro che volessero approfondire le conoscenze di questo dispositivo o volessero maggiori informazioni su come programmarlo, possono far riferimento al documento numero 939775009611 (order number Philips) che può essere gratuitamente richiesto alla Philips o scaricato dal sito.

3.6 La Compact Flash

Sulla scheda UNI-PD-PXA l’interfaccia Compact Flash è stata ricavata direttamente dal PXA255 con l’esclusivo ausilio di due transceiver secondo quanto previsto nel do-cumento intel 278694-001.pdf al paragrafo 2.6.6 nella modalità single slot. I segnali di controllo non previsti direttamente sul PXA255 sono stati ricavati utilizzando dei pin GPIO. Il connettore CF è presente sul lato destro del box scheda. Il firmware di scheda non integra attualmente il driver CF.

Per ulteriori dettagli su come gestire lo standard CF, il lettore può far riferimento al documento ‘CF+ and CompactFlash Specification Revision 1.4’.

3.7 La Multimedia Card

Il controller MMC presente nel PXA255 è compatibile con la specifica multimedia card system versione 2.1 con l’unica eccezione che il trasferimento a singolo byte ed a 3 byte non è supportato. Sulla scheda UNI-PD-PXA è presente un socket per SD card che però non presenta la relativa fessura sul bordo scheda. Qualora il lettore volesse fare uso della interfaccia multimedia card può derivare i segnali necessari dai connet-

Page 26: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

26

tori di espansione di cui parleremo più avanti. Il firmware di scheda non integra at-tualmente il driver MMC.

DC3P3V

4.7KR99

DC3P3V

SA_MMDAT

SD Socket

DNIIFSD

SA_MMCCLK

C61

0.1U

F

DNI IF MMC

Bottom Mount

CH

EC

K !!

J2

1

2

3

4

5

6

7

8

11 12

910

CD_DAT3

CMD

VSS1

VDD

CLK

VSS2

DAT0

DAT1

WP

CO

MM

DAT2C

D

nMMC_DETECT

MMC_PWR

C47270PF

T7

100K

R11

2 DNIIFMMC

MMC_ON

100K

R10

7

VCC

+C46

4.7u

F 35

V

R102

0

MIC5207-3.3BM53.3V LDO REG180ma

LE33

U13

MIC5207-3.3BM5

34

5

2

1

ENBYP

VOUT

GND

VIN

SA_MMCMD

DC3P3V DNIIFSD

DC3P3V

DC3P3V

MMC_WP

R108

47K

R10

5

0

MMC_CS0

100K

R11

3

3.8 Le porte seriali

RS485 RS232BT RS232FF

Le porte seriali asincrone presenti nel PXA255 sono 4; per 3 di esse i relativi segnali sono stati riportati su altrettanti connettori posti nella parete posteriore del box contenente la scheda UNI-PD-PXA. La porta seriale full modem (FFUART) è stata connessa al connettore a vaschetta (CANON a 9 pin - Standard RS232) posto sul re-tro del box in prossimità dell’interruttore di accensione. Fra i segnali del PXA255 ed il connettore è stato interposto un ICL3244ECAI al fine di adattare i livelli di tensione allo standard RS232. Attualmente la connessione con l’host computer avviene attra-verso questa porta. La seconda porta è anche denominata BTUART dove BT sta per blutooth, per indicare che il suo transfer rate può essere programmato esattamente uguale al transfer rate di una connessione blutooth. Sulla scheda UNI-PD-PXA anche questa porta è stata connessa ad un secondo connettore a vaschetta posto sul retro. Mentre la FFUART presenta tutti i segnali di controllo necessari ad esempio per la connessione con un modem, la BTUART ha solo due segnali di controllo il CTS e l’RTS.

Page 27: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

27

I connettori a vaschetta sono stati collegati secondo lo standard RS232 e quindi pos-sono essere utilizzati dei cavi per connessioni seriali standard PC.

Con la terza porta seriale del PXA255 è stata realizzata una connessione RS485 resa disponibile sul retro della scheda.

La quarta porta seriale (HWUART) è stata diretta sui connettori di espansione della scheda.

3.9 I connettori di espansione (J6, J7)

La scheda UNI-PD-PXA è stata munita di due connettori di espansione (J6,J7) facil-mente raggiungibili rimovendo il coperchio trasparente in plexiglas. Attraverso questi connettori viene reso disponibile il bus del PXA255 opportunamente isolato e le peri-feriche non esternate sul box.

EXT_nOE

SA_nPOEEXT_D5SA_FF_CTS

SA_SDATA_IN

EXT_nWR

SA1111_IRQ_CF_BVD1

EXT_D7

SA_DQM_1DC3P3V

PRDY_BSYn

SA_FF_RTSSA_BITCLK

GPIO_21

GPIO_11EXT_A7EXT_A9

nPCD0

EXT_D9

EXT_D0

SA_PSKTSEL

MMC_ON

DC3P3V

GPIO_1

MMC_CS0

EXT_D15

nMMC_DETECT

EXT_RD_nWR

SA_FF_DSR

SA_nPREG

DC3P3V

EXT_A5

VCC

SA_nPIOREXT_D1

SA_FF_DCDSA_SYNC

EXT_D4

PADDR_ENn

DC3P3V

SA_DQM_0

EXT_A2

EXT_D11

SA_FF_DTR

SA_nAC97_RESET

GPIO_22

SA_MMCCLK

GFX_IRQ_CF_BVD2 RS232_VALID

EXT_A0

SA_MMCMD

EXT_A8

J6

STRIP 25X2 FEMMINA

13579

111315171921232527293133353739

246810121416182022242628303234363840

41 4243 4445 4647 4849 50

SA_nPWAIT

EXT_D6

EXT_A1

SA_nCS_3

SA_nPCE_2

DC3P3VDC3P3V

SA_nCS_4

EXT_D10

EXT_D3

VCC

SA_FF_RI

EXT_A3

J7

STRIP 25X2 FEMMINA

13579

111315171921232527293133353739

246810121416182022242628303234363840

41 4243 4445 4647 4849 50DC3P3V

EXT_A4

EXT_D14SA_PWM_0

nCHRGR_PRESENT

SA_SDATA_OUT

SA_FF_RXD

SA_nPWE

SA_nIOIS16

EXT_A10

GPIO_10

EXT_D2

SA_MMDAT

EXT_D8

EXT_D13

GPIO_19

SA_nPIOW

GPIO_20

AC97_IRQ

EXT_A11

EXT_D12

DC3P3V

GPIO_0

nPCD1

SA_FF_TXD

DC3P3V

SA_nPCE_1

VCC

EXT_A6

Grazie a ciò è possibile realizzare delle schede plug-in, non previste inizialmente, ido-nee alle applicazioni più generiche e utilizzabili direttamente sulla scheda UNI-PD-PXA.

3.10 L’interfaccia LCD

La scheda UNI-PD-PXA presenta una interfaccia LCD general purpouse che consente l’uso diretto di quasi tutti gli LCD disponibili sul mercato:

• STN single panel • STN dual panel • TFT • Monocromatici • Colori (fino a 16 bit di profondità) • Risoluzione fino a 640x480

Nei box installati presso l’università di Padova è stato utilizzato un LCD STN 320x240 con 65536 colori collegato al connettore JP5.

Page 28: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

28

Oltre al connettore JP5 utilizzato per l’LCD attuale, è presente il connettore J15 che rende disponibile l’interfaccia LCD nella sua completezza, per cui sarebbe semplice sostituire l’LCD attuale con altri tipi di LCD.

L_DD_7

L_LCLK

XX

R16

9

L_DD_5

DC3P3V

L_DD_13

L_DD_6

JP5

1

3

2

4

5

6

7

8

9

10

11

12

13

14

15

16

L_DD_11

DC3P3V

L_DD_6

POT

10K LIN

L_DD_15

L_DD_0

L_DD_9

L_DD_4

L_PCLK

L_DD_5L_DD_12

DC3P3V

L_DD_2

LCD Connector

L_DD_3

J15

LCD-TFT

123456789

101112131415161718192021222324252627282930313233

GNDCKHsyncVsyncGNDR0R1R2R3R4R5GNDG0G1G2G3G4G5GNDB0B1B2B3B4B5GNDENABVccVccR/LU/DV/QGND

L_DD_3

L_DD_10

L_DD_14

L_LCLK

YY

R17

0

L_PCLK

L_FCLK

L_FCLK

L_DD_0

L_DD_4

L_DD_7

L_DD_1

LCD_PWR_ON

L_DD_1

L_DD_2

L_DD_8

Page 29: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

29

CAPITOLO IV

L’ambiente di sviluppo su PC

Lo scopo di questo capitolo è di descrivere:

- l’ambiente di sviluppo del software, - gli strumenti utilizzati in questo ambiente e - l’interazione con il target in fase di debug del codice sviluppato.

Prima di iniziare la descrizione dei tre punti sopraccitati è conveniente fare una pre-messa introduttiva, per giustificare alcune scelte:

Gli strumenti di sviluppo del software, ovvero compilatore, assemblatore e linker fan-no parte dei tool della famiglia “GNU” della quale fanno parte anche altri tipi di tool, quali editor, parser, file-utility ecc… . Questi tool sono stati creati originariamente per il sistema operativo “Linux” e, nel corso del tempo, sono stati “portati” (adattati) ad altri sistemi operativi quali QNX e “win32”. In questo contesto particolare ci si ri-ferisce alla versione per Win32; da notare però che le modalità di utilizzo ed i risulta-ti ottenuti dai tool di sviluppo su un altro sistema operativo in sostanza non cambiano.

Gli strumenti “GNU” portati su sistemi operativi basati su “win32”, ovvero Windows 95-98-ME e windows-NT-2000-XP si adattano molto bene ad essere utilizzati in un ambiente chiamato “CYGWIN”, nel quale sono stati “portati” un gran numero di tool della GNU. Si ricorda comunque che l’utilizzo dell’ambiente “CYGWIN” non è stretta-mente necessario, ma è fortemente consigliato proprio per la presenza di questi ulte-riori tool frequentemente utilizzati per lo sviluppo del software, non ultimo ad esem-pio il programma “make”.

Page 30: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

30

4.1 L’ambiente di sviluppo del software

Come già accennato, l’ambiente in cui si opera è “CYGWIN”. CYGWIN permette di e-mulare l’ambiente LINUX in sistemi operativi tipo WIN32 ed è composto sostanzial-mente da due entità:

- Una libreria DLL (cygwin1.dll), la quale ha le funzioni di emulare le chia-mate al sistema operativo “LINUX”.

- Una serie di tool GNU , sviluppati in LINUX ed adattati all’ambiente WIN32.

In questo ambiente è possibile sviluppare software che fa uso delle API standard WIN32 e/o delle API di CYGWIN; questo aspetto permette il “porting” di software sviluppato in Linux o, più in generale, in Unix.

L’ambiente mette a disposizione uno shell “Bash” del tutto simile a quello che si trova comunemente in Linux.

L’ambiente CYGWIN è supportato da tutte le versioni a 32 bit di Windows, tranne che Windows CE.

Da esperienze pregresse si consiglia comunque di installare CYGWIN su un Sistema Operativo Windows 2000 o Windows XP, dove si hanno prestazioni migliori in termini di stabilità.

4.2 Gli strumenti di sviluppo del software

Di seguito si riporta una lista degli strumenti maggiormente utilizzati per lo sviluppo del software di tipo “embedded”:

- Compilatore; - Linker; - Assemblatore; - Debugger; - Make;

Il compilatore C della GNU, conosciuto come gcc (che è il comando per richiamare il compilatore) è uno dei più versatili ed evoluti; in particolare, questo compilatore è sta-to adattato a moltissime piattaforme per esempio:

- x86 per ambiente linux; - x86 per ambiente WIN32;

Solitamente gcc è utilizzato per sviluppo del software “nativo”: ad esempio, mediante il compilatore gcc su x86 per Linux si sviluppa del codice destinato ad essere eseguito sul medesimo processore x86 (per esempio pentium) equipaggiato con sistema operati-vo Linux.

Page 31: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

31

Diversamente si procede, di solito, per lo sviluppo di software di tipo embedded: per le schede UNI-PD-PXA, ad esempio, c’è la necessità di sviluppare del codice per un processore tipo Xscale su un normale PC, ovvero su un host x86 equipaggiato con si-stema operativo tipo WIN32 (per es. Windows 2000). Questa operazione viene chia-mata “cross-compilazione”; anche la cross-compilazione viene supportata egregiamente dai compilatori GNU.

Esistono diverse distribuzioni del compilatore gcc, tutte sostanzialmente equivalenti. Con riferimento al cross-compilatore per target Xscale, su Host Win32 basato su x86, sono di interesse le seguenti due distribuzioni, tra loro equivalenti:

- i686-pc-cygwin-x-xscale-elf.zip ;scaricabile dal sito GnuPro toolKit; - XscaleElfInstallation.exe ;scaricabile dal sito della OCDEMON;

La prima versione è un file compresso tipo “zip”: la decompressione genera un directory “xscale-020523” nel quale è contenuto tutto.

La seconda versione viene rilasciata da Ocdemon, produttore di tool hardware (quali In Circuit Debugger, emulatori ecc… ). Questa versione consiste di un file eseguibile il quale provvede automaticamente all’installazione (self-extracting). Questa versione richiede l’esplicita presenza di CygWin, anche se, come già detto, non sarebbe stret-tamente necessaria.

Per entrambe le versioni, il comando per richiamare il compilatore è xscale-elf-gcc

Nella prima versione, il directory in cui si trova il compilatore è: C:\cygwin\xscale-020523\H-i686-pc-cygwin\bin

nella seconda versione, il directory è: C:\cygwin\usr\local\xscale-elf\H-i686-pc-cygwin\bin

In questi directory, oltre al file “xscale-elf-gcc.exe”, si trovano i file contenenti i programmi eseguibili di tutti gli altri tool,.

Il comando che richiama il cross-compilatore ha il seguente significato:

xscale-elf-gcc

il compilatore è per target Xscale

produce codice rilocabile tipo “ELF”

questo tool è il compilatore (Gnu C Compiler)

Page 32: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

32

Alcuni degli altri tool che interessano, sono:

Assemblatore: xscale-elf-as Archiver: xscale-elf-ar Linker: xscale-elf-ld Listing symbol from obj file: xscale-elf-nm Display info from obj file: xscale-elf-objdump

Di seguito vengono riportati alcuni esempi di utilizzo dei tool partendo da codice sor-gente fornito come esempio nella versione OCDEMON (vedi contenuto del directory /usr/local/xscale-elf/H-i686-pc-cygwin/xscaleDemoLubbock), in modo da illustrare le opzioni più utilizzate per poter iniziare a sviluppare del codice.

Si voglia compilare il programma situato nel file test.c, contenente il seguente codi-ce sorgente in linguaggio C: int varc, vard; __gccmain() { testcode(); } testcode() { int i, vara, varb, *ptr; ptr = (int *)0xa00c000; varc = 0x12345678; for (i = 0; i < 0x100; i++) { vara = varb + 2; varb = vara; inc_var(); } } inc_var() { varc++; vard = varc; } exit() { while(1); } atexit() { while(1); }

Page 33: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

33

Per generare il modulo oggetto a partire dal modulo sorgente contenuto nel file test.c, si invoca il compilatore C, tramite il comando gcc con le seguenti opzioni: xscale-elf-gcc -c test.c

il modulo oggetto rilocabile, di tipo ELF viene generato nel file test.o.

E’ possibile constatare l’effettivo formato ELF analizzando il file mediante un editor esadecimale e verificando che l’header riporti, nei primi 4 byte, la seguente sequenza: 7f 45 4c 46 (gli ultimi 3 byte rappresentano la stringa ELF in codifica ASCII).

Per ottenere il modulo eseguibile, nel file test, si invoca il linker in questo modo: xscale-elf-ld –o test test.o

si può constatare che il linker produce il seguente messaggio di warning:

Warning: cannot find entry symbol _start; defaulting to 00008000

Questo messaggio segnala che si è tentato di generare un file contenente del codice assoluto, eseguibile dal processore, ma senza aver specificato ove si trova la prima i-struzione da eseguire e senza aver dato alcuna indicazione di dove allocare la sezione contenente il codice stesso.

Spesso si introduce un segmento di codice aggiuntivo con cui viene preparato l’ambiente in grado di ospitare il codice prodotto dal compilatore C. Questo segmento di codice è scritto in linguaggio assembly ed è contenuto in un file individuato di con-suetudine con il nome crt0.s

Di seguito si riporta il contenuto di crt0.s: /* Sample initialization file */ .extern __gccmain .extern exit /* .text is used instead of .section .text so it works with arm-aout too*/ .text .code 32 .align 0 .global _mainCRTStartup .global _start .global start start: _start: _mainCRTStartup: /* Start by setting up a stack */ /* Set up the stack pointer to end of bss */ ldr r3, .LC2 mov sp, r3 sub sl, sp, #512 /* Still assumes 512 bytes below sl */

Page 34: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

34

mov a2, #0 /* Second arg: fill value */ mov fp, a2 /* Null frame pointer */ mov r7, a2 /* Null frame pointer for Thumb */ ldr a1, .LC1 /* First arg: start of memory block */ ldr a3, .LC2 /* Second arg: end of memory block */ sub a3, a3, a1 /* Third arg: length of block */ mov r0, #0 /* no arguments */ mov r1, #0 /* no argv either */ bl __gccmain bl exit /* Should not return */ mov r0,r1 mcr p15,0,r0,c7,cr5,0 /* INVALIDATE ICACHE & BTB */ /* For Thumb, constants must be after the code since only positive offsets are supported for PC relative addresses. */ .align 0 .LC1: .word __bss_start__ .LC2: .word __bss_end__

In questo segmento di codice normalmente sono specificate le seguenti fasi:

- dichiarazione del label che individua il punto di partenza del segmento di co-dice “_start”;

- inizializzazione dello stack-pointer del processore, normalmente alla fine del segmento “bss”;

- preparazione dei parametri da passare alla prima chiamata alla funzione ‘C’; - salto alla funzione ‘C’ e, nella maggior parte dei casi, senza ritornare a que-

sto segmento.

Il file assembly crt0.s deve essere opportunamente assemblato in modo da creare un modulo oggetto (nel file ctr0.o) e poi, mediante il linker, deve essere collegato al modulo oggetto preparato precedentemente (in test.o), in modo da ottenere un mo-dulo eseguibile utilizzabile dal processore. I comandi con cui si ottiene ciò sono i se-guenti:

fase di assemblaggio: xscale-elf-as -o crt0.o crt0.s

fase di costruzione del modulo eseguibile (nel file all) tramite l’unione (linking) dei 2 moduli oggetto: xscale-elf-ld –o all crt0.o test.o

Adesso il linker non genera più il messaggio di “warning”, in quanto i due file crt0.s e test.c non lasciano irrisolto alcun label o riferimento, nemmeno il punto di partenza del codice, _start, che si trova in crt0.s. L’indirizzo fisico di _start è stato asse-

Page 35: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

35

gnato dal linker per default ancora al valore 0x8000, come si può verificare dall’header ELF del file “all”:

In effetti la fase di linking necessita delle informazioni riguardanti le allocazioni in memoria dei segmenti di codice e dati. Per questo motivo, usualmente, al linker viene fornito anche un file contenente queste informazioni. Si riporta di seguito un esempio di un tale file (file: ldscript): SECTIONS { . = 0xa0000000; .text : { *(.text) } . += 0x10; .data : { *(.data) } . += 0x10; .bss : { *(.bss) } __bss_start__ = .; . += 0x1000; __bss_end__ = .; . += 0x1000; PROVIDE (__stack = .); _end = .; .debug_info 0 : { *(.debug_info) } .debug_abbrev 0 : { *(.debug_abbrev) } .debug_line 0 : { *(.debug_line) } .debug_frame 0 : { *(.debug_frame) } /* .debug_str 0 : { *(.debug_str) } */ /* .debug_loc 0 : { *(.debug_loc) } */ /* .debug_macinfo 0 : { *(.debug_macinfo) } */ }

In questo codice è possibile individuare l’informazione che specifica l’indirizzo iniziale del segmento “text”, cioè del codice eseguibile, che viene definito all’indirizzo assolu-to 0xa0000000;

Con il seguente comando viene eseguita la fase di linking utilizzando le informazioni contenute in “ldscript”:

Questi 4 byte indicano l’indirizzo di allocazione del codice contenuto nel file (secondo la convenzione Little Endian)

Page 36: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

36

xscale-elf-ld -o all –Tldscript crt0.o test.o

Esaminando il contenuto del file “all”, si può constatare l’effettiva allocazione del codice all’indirizzo 0xa0000000:

Nei casi in cui la struttura di allocazione delle sezioni “text”, “data” e “bss” è più sem-plice, è possibile usare le opzioni –Ttext ADDRESS, -Tdata ADDRESS e –Tbss AD-DRESS per specificare gli indirizzi iniziali delle varie sezioni. Si riporta di seguito un esempio: xscale-elf-ld -o all –Ttext 0xa0000000 crt0.o test.o

Come ulteriore verifica della correttezza dell’allocazione del segmento “text”, è pos-sibile disassemblare il modulo eseguibile contenuto nel file “all”, mediante il coman-do: xscale-elf-objdump –D all > all.asm

Con questo comando si ricostruiscono le istruzioni assembly simboliche, a partire dal codice binario del modulo eseguibile.

Si ottiene come risultato il file all.asm, il cui contenuto è riportato qui di seguito: all: file format elf32-littlearm Disassembly of section .text: a0000000 <_mainCRTStartup>: a0000000: e59f3038 ldr r3, [pc, #38] ; a0000040 <_mainCRTStartup+0x40> a0000004: e1a0d003 mov sp, r3 a0000008: e24dac02 sub r10, sp, #512 ; 0x200 a000000c: e3a01000 mov r1, #0 ; 0x0 a0000010: e1a0b001 mov r11, r1 a0000014: e1a07001 mov r7, r1 a0000018: e59f001c ldr r0, [pc, #1c] ; a000003c <_mainCRTStartup+0x3c> a000001c: e59f201c ldr r2, [pc, #1c] ; a0000040 <_mainCRTStartup+0x40> a0000020: e0422000 sub r2, r2, r0 a0000024: e3a00000 mov r0, #0 ; 0x0 a0000028: e3a01000 mov r1, #0 ; 0x0 a000002c: eb000004 bl a0000044 <__gccmain> a0000030: eb000035 bl a000010c <exit> a0000034: e1a00001 mov r0, r1 a0000038: ee070f15 mcr 15, 0, r0, cr7, cr5, {0} a000003c: a0000174 andge r0, r0, r4, ror r1 a0000040: a0001174 andge r1, r0, r4, ror r1

0xa0000000 (Little Endian)

Page 37: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

37

a0000044 <__gccmain>: a0000044: e1a0c00d mov r12, sp a0000048: e92dd800 stmdb sp!, {r11, r12, lr, pc} a000004c: e24cb004 sub r11, r12, #4 ; 0x4 a0000050: eb000000 bl a0000058 <testcode> a0000054: e91ba800 ldmdb r11, {r11, sp, pc} a0000058 <testcode>: a0000058: e1a0c00d mov r12, sp a000005c: e92dd800 stmdb sp!, {r11, r12, lr, pc} a0000060: e24cb004 sub r11, r12, #4 ; 0x4 a0000064: e24dd010 sub sp, sp, #16 ; 0x10 a0000068: e3a0340a mov r3, #167772160 ; 0xa000000 a000006c: e2833903 add r3, r3, #49152 ; 0xc000 a0000070: e50b301c str r3, [r11, -#28] a0000074: e59f3048 ldr r3, [pc, #48] ; a00000c4 <testcode+0x6c> a0000078: e59f2048 ldr r2, [pc, #48] ; a00000c8 <testcode+0x70> a000007c: e5832000 str r2, [r3] a0000080: e3a03000 mov r3, #0 ; 0x0 a0000084: e50b3010 str r3, [r11, -#16] a0000088: e51b3010 ldr r3, [r11, -#16] a000008c: e35300ff cmp r3, #255 ; 0xff a0000090: da000000 ble a0000098 <testcode+0x40> a0000094: ea000009 b a00000c0 <testcode+0x68> a0000098: e51b3018 ldr r3, [r11, -#24] a000009c: e2832002 add r2, r3, #2 ; 0x2 a00000a0: e50b2014 str r2, [r11, -#20] a00000a4: e51b3014 ldr r3, [r11, -#20] a00000a8: e50b3018 str r3, [r11, -#24] a00000ac: eb000006 bl a00000cc <inc_var> a00000b0: e51b3010 ldr r3, [r11, -#16] a00000b4: e2832001 add r2, r3, #1 ; 0x1 a00000b8: e50b2010 str r2, [r11, -#16] a00000bc: eafffff1 b a0000088 <testcode+0x30> a00000c0: e91ba800 ldmdb r11, {r11, sp, pc} a00000c4: a000016c andge r0, r0, r12, ror #2 a00000c8: 12345678 eornes r5, r4, #125829120 ; 0x7800000 a00000cc <inc_var>: a00000cc: e1a0c00d mov r12, sp a00000d0: e92dd800 stmdb sp!, {r11, r12, lr, pc} a00000d4: e24cb004 sub r11, r12, #4 ; 0x4 a00000d8: e59f2024 ldr r2, [pc, #24] ; a0000104 <inc_var+0x38> a00000dc: e59f3020 ldr r3, [pc, #20] ; a0000104 <inc_var+0x38> a00000e0: e59f201c ldr r2, [pc, #1c] ; a0000104 <inc_var+0x38> a00000e4: e5921000 ldr r1, [r2] a00000e8: e2812001 add r2, r1, #1 ; 0x1 a00000ec: e5832000 str r2, [r3] a00000f0: e59f3010 ldr r3, [pc, #10] ; a0000108 <inc_var+0x3c> a00000f4: e59f2008 ldr r2, [pc, #8] ; a0000104 <inc_var+0x38> a00000f8: e5921000 ldr r1, [r2] a00000fc: e5831000 str r1, [r3] a0000100: e91ba800 ldmdb r11, {r11, sp, pc} a0000104: a000016c andge r0, r0, r12, ror #2 a0000108: a0000170 andge r0, r0, r0, ror r1 a000010c <exit>: a000010c: e1a0c00d mov r12, sp a0000110: e92dd800 stmdb sp!, {r11, r12, lr, pc} a0000114: e24cb004 sub r11, r12, #4 ; 0x4 a0000118: e1a00000 nop (mov r0,r0) a000011c: ea000000 b a0000124 <exit+0x18> a0000120: ea000000 b a0000128 <exit+0x1c>

Page 38: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

38

a0000124: eafffffc b a000011c <exit+0x10> a0000128: e91ba800 ldmdb r11, {r11, sp, pc} a000012c <atexit>: a000012c: e1a0c00d mov r12, sp a0000130: e92dd800 stmdb sp!, {r11, r12, lr, pc} a0000134: e24cb004 sub r11, r12, #4 ; 0x4 a0000138: e1a00000 nop (mov r0,r0) a000013c: ea000000 b a0000144 <atexit+0x18> a0000140: ea000000 b a0000148 <atexit+0x1c> a0000144: eafffffc b a000013c <atexit+0x10> a0000148: e91ba800 ldmdb r11, {r11, sp, pc} Disassembly of section .glue_7t: Disassembly of section .glue_7: Disassembly of section .data:

Esaminando il codice disassemblato, è possibile ricavare alcune informazioni sulla cor-rettezza di ciò che si è ottenuto: per esempio la colonna di sinistra (contenente gli in-dirizzi di memoria) consente di constatare subito che il codice è effettivamente allo-cato a partire dall’indirizzo 0xa0000000.

Si può verificare la correttezza dell’inizializzazione dello stack-pointer effettuata nelle prime due istruzioni assembly contenute in crt0.s : /* Set up the stack pointer to end of bss */ ldr r3, .LC2 mov sp, r3

che, disassemblate, sono rappresentate nel file all.asm come segue: a0000000: e59f3038 ldr r3, [pc, #38] ; a0000040 <_mainCRTStartup+0x40> a0000004: e1a0d003 mov sp, r3

Viene caricato in r3 il valore contenuto all’indirizzo 0xa0000040 (label .LC2) corri-spondente al valore 0xa0001174 (ovvero __bss_end__): a0000040: a0001174 andge r1, r0, r4, ror r1

(si tenga presente che il disassemblatore interpreta come istruzione anche ciò che i-struzione non è, per cui il disassemblaggio di a0001174, che è un indirizzo di memoria, produce un’istruzione non significativa).

Successivamente il registro sp viene caricato con il valore contenuto in r3.

Il valore 0xa0001174 viene calcolato nel processo di linking in funzione delle informa-zioni di allocazione contenute nel file ldscript.

Un ulteriore strumento di verifica consiste nella generazione dei simboli dal file “all”: mediante il seguente comando:

xscale-elf-nm all > all.sym

Il risultato, contenuto nel file all.sym, è riportato qui di seguito:

Page 39: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

39

a0000044 t .gcc2_compiled.

a0001174 A __bss_end__ Indirizzo della fine del segmento BSS, dove è stato inizializzato lo stack-pointer 0xa0001174

a0000174 A __bss_start__ a0000044 T __gccmain a0002174 A _end

a0000000 T _mainCRTStartup Entry point, come previsto, a 0xa0000000 a0000000 T _start a000012c T atexit a000010c T exit a00000cc T inc_var a0000000 T start a0000058 T testcode a000016c B varc a0000170 B vard

Una ulteriore verifica molto interessante può essere fatta mediante la generazione del mapping-file, che si ottiene aggiungendo al comando di linking l’opzione –M e la ri-direzione da stdout verso un file (per esempio all.map):

xscale-elf-ld –o all –Tldscript crt0.o test.o –M > all.map

Il file risultante contiene le seguenti informazioni: Allocating common symbols Common symbol size file varc 0x4 test.o vard 0x4 test.o Memory Configuration Name Origin Length Page Attributes *default* 0x00000000 0xffffffff 0 Linker script and memory map 0xa0000000 .=0xa0000000 .text 0xa0000000 0x14c *(.text) .text 0xa0000000 0x44 crt0.o 0xa0000000 _mainCRTStartup 0xa0000000 _start 0xa0000000 start .text 0xa0000044 0x108 test.o 0xa0000044 __gccmain 0xa00000cc inc_var 0xa0000058 testcode 0xa000012c atexit 0xa000010c exit .glue_7t 0xa000014c 0x0 .glue_7 0xa000014c 0x0 0xa000015c .=(.+0x10)

Page 40: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

40

.data 0xa000015c 0x0 *(.data) 0xa000016c .=(.+0x10) .bss 0xa000016c 0x8 *(.bss) COMMON 0xa000016c 0x8 test.o 0x0 (size before relaxing) 0xa000016c varc 0xa0000170 vard 0xa0000174 __bss_start__=. 0xa0001174 .=(.+0x1000) 0xa0000174 __bss_end__=. 0xa0001174 .=(.+0x1000) 0xa0000174 PROVIDE (__stack, .) 0xa0000174 _end=. .debug_info *(.debug_info) .debug_abbrev *(.debug_abbrev) .debug_line *(.debug_line) .debug_frame *(.debug_frame) LOAD crt0.o LOAD test.o OUTPUT(all elf32-littlearm)

Normalmente nello sviluppo di software tutte queste fasi sono eseguite in modo auto-matico mediante il tool “make” ed il corrispondente file “makefile” in cui sono specifi-cate, mediante una opportuna sintassi, le varie fasi di sviluppo ed i risultati che si vo-gliono ottenere.

Nel makefile di esempio riportato di seguito si possono riconoscere facilmente tutte le fasi descritte precedentemente: # Makefile for Xscale Demo PROC=xscale TYPE=elf PATH=/usr/local/$(PROC)-$(TYPE)/H-i686-pc-cygwin/bin:/usr/bin LIBPATH=/usr/local/$(PROC)-$(TYPE)/H-i686-pc-cygwin/$(PROC)-$(TYPE)/lib INCPATH=/usr/local/$(PROC)-$(TYPE)/H-i686-pc-cygwin/$(PROC)-$(TYPE)/include CC=$(PROC)-$(TYPE)-gcc AS=$(PROC)-$(TYPE)-as AR=$(PROC)-$(TYPE)-ar LD=$(PROC)-$(TYPE)-ld NM=$(PROC)-$(TYPE)-nm OBJDUMP=$(PROC)-$(TYPE)-objdump LDSCRIPT=ldscript

Page 41: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

41

# Make little endian code. test_le: test.c Makefile $(LDSCRIPT) crt0.o

$(CC) -g -c test.c

$(CC) -g -c -o crt0.o crt0.S # $(NM) test.o $(LD) -g -v -T $(LDSCRIPT) -o test crt0.o test.o

$(NM) test > test.map

/bin/cp gdbinit_le gdb.ini #make big endian code. test_be: test.c Makefile $(LDSCRIPT) crt0.o $(CC) -mbig-endian -g -c test.c $(CC) -mbig-endian -g -c -o crt0.o crt0.S # $(NM) test.o $(LD) -EB -g -v -T $(LDSCRIPT) -o test crt0.o test.o $(NM) test > test.map /bin/cp gdbinit_be gdb.ini dump: $(OBJDUMP) --all-headers test dis: $(OBJDUMP) --disassemble test clean: rm *.o rm test rm *.map rm gdb.ini

Perciò quando si richiama il seguente comando: make test_le

avviene la generazione di un file chiamato test contenente codice eseguibile per il processore, oltre ovviamente ai file risultanti dalle fasi intermedie e ai vari map-file e symbol-file.

Un ulteriore tool che può essere utile è quello che fornisce la dimensione (in byte) del-le varie sezioni contenute nel modulo eseguibile: xscale-elf-size all

viene generato il seguente report:

text data bss dec hex filename 332 0 8 340 154 all

Dimensione del segmento “text”

Dimensione del segmento “data”

Dimensione del segmento “bss”

Dimensione tota-le in base 10

Dimensione tota-le in base 16

Compilazione di test.c test.c

Assemblaggio di crt0.s

Linking di test.o e crt0.o; info per alloc. in ldscript

Generazione simboli dall’eseguibile test

Page 42: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

42

Naturalmente tutti i tool riportati prevedono moltissime opzioni; per approfondimenti si consiglia sia di fare riferimento alla grande quantità di documentazione reperibile in internet, sia di utilizzare il manuale in linea di cygwin per la versione nativa x86:

man gcc man as man ld

tenendo presente che la maggior parte delle opzioni vale in tutte le versioni di target.

Esiste anche un help in linea dei tool per xscale, richiamabile nel seguente modo: xcale-elf-gcc --help xcale-elf-as --help xcale-elf-ld --help -------- ---

In modo simile per tutti gli altri tool disponibili.

Di seguito si riporta un riassunto schematico delle varie fasi di sviluppo utilizzate nell’esempio riportato precedentemente:

crt0.s

test.o crt0.o

ldscript

all all.map

all.asm

xscale-elf-as –o crt0.o crt0.s

xscale-elf-gcc –c test.c

xscale-elf-ld –o all-Tldscript crt0.o test.o –M > all.map

xscale-elf-objcopy –D all > all.asm

all.sym

xscale-elf-nm all > all.sym

test.c

Page 43: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

43

4.3 Interazione con il target e fase di debug del codice sviluppato

Il debugger “gdb” (Gnu–DeBugger) viene utilizzato per individuare e correggere even-tuali errori presenti nel codice in via di sviluppo. Esso permette di analizzare il flusso del codice eseguibile impostando breakpoint e di controllare lo stato delle variabili, dei registri e degli stack.

Informazioni dettagliate e complete sul debugger gdb si possono trovare all’indirizzo: http://www.gnu.org/softwre/gdb/gdb.html qui ci si limita a riportare solo alcune delle informazioni che servono per l’uso di gdb.

Gdb si presenta, nella sua forma più tradizionale, come un programma a linea di co-mando testuale, ma nelle versioni più recenti è presente anche una interfaccia grafica.

È utile tenere presenti le differenze tra le tre diverse modalità di funzionamento del debugger gdb: local debugging, stand-alone simulator, remote debugging.

- Local debugging: Il “local debugging” avviene quando il software sviluppato su un host deve esse-re eseguito e controllato sullo stesso processore host. In questo caso il proces-sore host ed il processore target coincidono, il tool gdb utilizzato deve essere di tipo “nativo” per quel tipo di host.

- Stand-alone simulator: Questa modalità di funzionamento del gdb è utilizzata quando non si ha la di-sponibilità dal target. Per attuare questa modalità è necessario specificare, all’avvio di una sessione di gdb, che la connessione è verso il simulatore “sim”.

Il gdb è in grado di simulare l’architettura del core Xscale, ma, come avviene per tutti i simulatori, non sono rispettati i tempi reali di esecuzione delle istru-zioni; anzi questi tempi sono fortemente dipendenti dalla macchina host sulla quale avviene la simulazione; un’altra limitazione del simulatore è che di fatto esso non è un simulatore a livello di scheda, ovvero non è possibile simulare il succedersi di eventi esterni come le richieste di interrupt o le richieste di DMA, se non con artifici molto complessi e difficili da mettere in atto e soprat-tutto non vengono simulate le periferiche esterne al core Xscale, come ad e-sempio MMU, UART ecc…

- Remote debugging: Quello che avviene spesso nello sviluppo di software di tipo embedded è che il processore host non coincide con il processore target, quindi emerge la necessi-ta di effettuare un “remote debugging” che consenta di eseguire e controllare un codice su un processore diverso da quello su cui è stato sviluppato.

Page 44: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

44

Nella modalità “remote debugger” il software gdb interagisce con il target me-diante una linea di comunicazione: tipicamente viene utilizzata una linea UART o un bus ethernet; spesso nelle fasi iniziali di sviluppo del firmware di base viene utilizzata anche la connessione JTAG (standard IEEE 1149.1).

Nel caso vengano utilizzate linee UART o bus ethernet, il target deve essere equipaggiato di software che provveda, oltre alla normale inizializzazione della scheda, anche alla inizializzazione della interfaccia che gestisce il canale di co-municazione e che attivi poi un segmento di codice che gestisca la comunicazio-ne tra target e host:

gdb-stub nel caso in cui il target sia equipaggiato di un semplice firmware tipo Bootloader, per esempio RedBoot;

oppure

gdb-server nel caso in cui il target sia già dotato di sistema operativo multitasking, ad esempio Linux.

Nel contesto particolare di questa esposizione, interessano le modalità “remote de-bugging” e “stand-alone simulator”.

Le procedure descritte in seguito valgono per entrambe le modalità di funzionamento a meno, per ovvie ragioni, di alcuni aspetti particolari riguardanti l’inizializzazione del-la connessione verso il target.

Di seguito viene illustrato come richiamare una sessione gdb per target “xscale”:

xscale-elf –gdb (apertura di una sessione con interfaccia grafica)

xscale-elf –gdb –nw (apertura di una sessione a linea di comando testuale)

L’apertura di una sessione del gnu-debugger necessita normalmente di una grande quantità di parametri. Alcuni di questi parametri possono essere forniti sulla linea di comando mentre viene invocato il gdb, come si è fatto per l’apertura di una sessione a linea di comando testuale, oppure si possono fornire mediante la console di gdb, digi-tandoli ad uno ad uno; ma il modo più comodo è quello di creare un file nominato “gdb.ini” contenente i parametri ed i comandi che si vuole siano eseguiti all’avvio di gdb. Se gdb viene avviato nello stesso directory dove è presente il file gdb.ini, i comandi contenuti in questo file verranno letti e conseguentemente eseguiti.

Se il nome del file contenente i parametri è diverso da gdb.ini allora è necessario informare il gdb mediante il comando: xscale-elf –gdb –command=FILE

dove FILE è il nome del file contenente i parametri ed i comandi.

Di seguito si riporta un esempio di apertura di sessione gdb con un target Xscale col-legato mediante linea seriale; quindi viene effettuato un “remote debugging” del codi-ce presentato come esempio nel paragrafo precedente.

Page 45: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

45

Come già accennato, sul target deve essere presente un firmware che comprende gdb-stub oppure gdb-server e i driver per il colloquio con la seriale.

In questo caso viene utilizzato il pacchetto “RedBoot”; questo è un bootloader che permette il caricamento su target di file eseguibili attraverso linea seriale in modalità Xmodem; permette inoltre di effettuare un debug minimale mettendo a disposizione alcuni comandi tipo “Read Memory” e “Modify Memory”. Redboot comprende anche il gdb-stub che permette di usare gdb su host per effettuare il debugger remoto.

Dopo aver predisposto la connessione seriale tra Host (PC) e target con un opportuno cavo, e dopo aver aperto una sessione VT100 (per esempio HyperTerminal) su host, configurata alla velocità del target (che in questo caso è 115200 Baud), al power-up del target vengono presentate su VT100 le seguenti informazioni: + RedBoot(tm) bootstrap and debug environment [ROM] Non-certified release, version v2_0b1 - built 10:36:35, May 11 2003 Platform: PXA2xx (XScale) Copyright (C) 2000, 2001, 2002, Red Hat, Inc. RAM: 0x00000000-0x04000000, 0x0000fcc8-0x02000000 available RedBoot>

Di particolare interesse è l’informazione sulla zona di RAM disponibile allo User.

La zona di RAM disponibile è 0x0000fcc8 0x02000000. Quindi sarà opportuno allo-care il codice visto precedentemente, per esempio all’indirizzo 0x10000, modificando il file ldscript in questo modo: SECTIONS { /* . = 0xa0000000; */

. = 0x00010000; .text : { *(.text) } . += 0x10; .data : { *(.data) } . += 0x10; .bss : { *(.bss) } __bss_start__ = .; . += 0x1000; __bss_end__ = .; . += 0x1000; PROVIDE (__stack = .); _end = .; .debug_info 0 : { *(.debug_info) } .debug_abbrev 0 : { *(.debug_abbrev) } .debug_line 0 : { *(.debug_line) } .debug_frame 0 : { *(.debug_frame) } /* .debug_str 0 : { *(.debug_str) } */ /* .debug_loc 0 : { *(.debug_loc) } */ /* .debug_macinfo 0 : { *(.debug_macinfo) } */ }

Page 46: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

46

E’ consigliabile cancellare i file prodotti dalla compilazione precedente con il comando: make clean

e successivamente effettuare la compilazione: make test_le

È importante che la compilazione dei file avvenga con l’opzione –g: questo permette che il codice eseguibile risultante sia controllabile dal debugger gdb. Per esempio:

xscale-elf-gcc –g –c test.c

in questo modo vengono aggiunte delle informazioni supplementari al file oggetto test.o, permettendo al codice eseguibile di essere sottoposto alla procedura di de-bugging.

È utile disporre di un file gdb.ini che operi le necessarie inizializzazioni all’avvio di gdb; di seguito se ne riporta un esempio: # file gdb.ini # Set up the environment for xscale gdb # in "REMOTE DEBUGGER" mode # Little endian mode. set endian little set prompt (xscale-gdb) # This connects to a UART set remotebaud 115200 target remote COM2 set output-radix 16 set input-radix 16 dir . # Create "setup" Macro to Set Registers to default values and load image # Open a Console Window in gdb and at the (xscale-gdb) prompt type "setup" # to run this macro define setup set $pc = 0x00010000 set $lr = 0x0 load test symbol-file test b __gccmain

Impostazione della velocità e della porta sulla quale avviene la comunicazione con il target

Definizione di una macro ri-chiamabile da console

Caricamento del codice eseguibile nel target e caricamento dei simboli.

Impostazione di un breakpoint alla funzione __gccmain (in test.c)

Page 47: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

47

Una volta creato il file gdb.ini come appena descritto, è possibile richiamare gdb me-diante il comando: xscale-elf-gdb.

In una nuova finestra (Source Window) viene presentata l’interfaccia grafica di gdb:

Se target e host sono connessi correttamente, i pulsanti contenuti nel “Toolbar” Step, Next, Finish, Continue, Step asm e Next asm (evidenziati nella figura precedente) so-no attivi e viene visualizzato il valore del Program Counter nell’apposita area; altrimen-ti la situazione del “Toolbar” si presenta come nella figura seguente:

Può essere utile aprire anche una finestra “console”: la modalità “console” viene utiliz-zata per fornire comandi particolari (che non sono tutti disponibili nell’interfaccia grafica). A fronte del prompt (xscale-gdb), richiamando la macro “setup” ( definita nel file gdb.ini), appaiono i seguenti messaggi: (xscale-gdb)setup Loading section .text, size 0x14c lma 0x10000

Start address 0x10000 , load size 332 Transfer rate: 2656 bits in <1 sec, 166 bytes/write. Breakpoint 1 at 0x10050: file test.c, line 5.

Apertura finestra “Console”

Page 48: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

48

(xscale-gdb)

Questi messaggi informano sulla corretta esecuzione del download del codice esegui-bile nel target.

A questo punto è possibile avviare l’esecuzione del codice, mediante il comando “conti-nue” (o brevemente “c”).

Appare la seguente situazione:

La linea di codice evidenziata in verde indica l’istruzione su cui l’esecuzione del pro-gramma si è interrotta a causa del breakpoint impostato nel file gdb.ini.

Da questa situazione è possibile continuare la procedura di debug del programma, fa-cendone proseguire l’esecuzione con i comandi step, next o con ulteriori impostazioni di breakpoint.

Questi (ed altri) comandi sono disponibili nel toolbar di “Source Windows”, come indi-cato nella seguente figura:

Page 49: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

49

Step

Next

Finish

Continue

Step Asm

Next Asm Register

Memory

Stack

Watch Expr.

Local Variables

BreakPoint

Console

Program Counter

Page 50: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

50

PULSANTI UTILIZZATI PER IL CONTROLLO DELL’ESECUZIONE DEL CODICE:

- Run: avvia l’esecuzione del programma; se il programma è già in esecuzione, lo fa ripartire dall’inizio;

- Step: esegue una sola istruzione;

- Next: esegue una sola istruzione, ma se l’istruzione è una chiamata a subroutine, esegue l’intera subroutine (posto che non vi siano breakpoint al suo inter-no);

- Finish: se è in corso l’esecuzione di una subroutine, ne prosegue l’esecuzione e si arresta subito dopo il ritorno al programma chiamante (posto che non si incontrino breakpoint prima);

- Continue: prosegue l’esecuzione del programma e si arresta al prossimo (eventuale) breakpoint;

- Step-asm: esegue una sola istruzione assembly;

- Next-asm: esegue una sola istruzione assembly, ma se l’istruzione è una chiamata a subroutine, esegue l’intera subroutine (posto che non vi siano breakpoint al suo interno).

PULSANTI UTILIZZATI PER ATTIVARE LE FINESTRE AUSILIARIE:

- Register: visualizza il contenuto dei registri e permette all’utente di modifi-carne il valore;

- Memory: visualizza porzioni di aree di memoria e permette all’utente di mo-dificarne il contenuto;

- Stack: visualizza la lista delle subroutine attive, con i livelli di chiamata;

- Local Variable: visualizza le variabili locali e permette all’utente di modificarne il valore;

- BreakPoint: visualizza i breakpoint impostati e ne permette l’abilitazione, la di-sabilitazione e la rimozione;

- Console: apre una finestra con l’una interfaccia GDB a linea di comando.

HELP IN LINEA PER L’USO DELL’INTERFACCIA GRAFICA

Maggiori informazioni su questi (e sugli altri) pulsanti presenti nell’interfaccia grafica, si possono ottenere utilizzando l’help in linea, cui si accede dal menù Help della fine-stra Source Window.

La lettura delle informazioni contenute in questo help in linea è molto utile per poter usare efficacemente il debugger gdb.

Page 51: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

51

USO DELL’INTERFACCIA A LINEA DI COMANDO

Tutte le possibilità messe a disposizione dall’interfaccia grafica sono, ovviamente, di-sponibili anche a livello di linea di comando nella finestra console; a questo proposito, di seguito sono elencati i comandi più comunemente utilizzati: - list: visualizza il codice sorgente di una funzione o di un file; - continue: prosegue l’esecuzione del programma e si arresta al prossimo (e-

ventuale) breakpoint; - break: imposta un breakpoint ad un indirizzo o ad una particolare linea di

codice; - step: esegue una sola istruzione; - next: esegue una sola istruzione, ma se l’istruzione è una chiamata a sub-

routine, esegue l’intera subroutine (posto che non vi siano break-point al suo interno);

- print: visualizza una variabile locale, o una o più locazioni di memoria; - info register: visualizza il contenuto dei registri; - set variable nome_variabile=nuovo_valore: modifica il valore di una variabile locale.

Dalla linea di comando è possibile accedere anche ad un help in linea digitando: help

questo comando provoca la visualizzazione della lista di comandi disponibili; è anche possibile ottenere le informazioni su un particolare comando, per esempio “step”, digi-tando: help step

verrà visualizzato: Step program until it reaches a different source line. Argument N means do this N times (or till program stops for another rea-son).

Page 52: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

52

ESEMPIO SINTETICO DI UNA SEMPLICE SESSIONE DI LAVORO

Si riporta qui di seguito, sinteticamente, la sequenza di operazioni e di comandi con cui si costruisce un semplice modulo sorgente assembly, lo si assembla, si crea il modulo eseguibile e se ne collauda l’esecuzione sulla scheda UNI-PD-PXA :

1. Per scrivere un programma assembly è necessario usare un “editor” (“Blocco Note” è più che sufficiente per programmi semplici; in alternativa si può anche usare “word”, con l’avvertenza di operare il salvataggio in formato text); il file in cui si salva il modulo sorgente deve avere l’estensione .s (es: prova.s).

2. Controllare che l’alimentatore sia collegato alla rete elettrica e alla scheda; controllare che il cavo seriale sia collegato al PC e alla scheda (porta seriale a-diacente alla porta USB); azionare l’interruttore principale sul retro della sche-da: si accende il led “ON” sul pannello frontale; il software di boot della scheda inizializza la memoria e la connessione seriale.

3. Assemblare il modulo sorgente (nell’es. contenuto in prova.s) con il comando: xscale-elf-as -al -gstabs -o prova.o prova.s > prova.l

(che produce il modulo oggetto in prova.o e il listing in prova.l).

4. Costruire il modulo eseguibile (nell’es. contenuto in prova.o) con il comando: xscale-elf-ld -g -Ttext 0x00100000 -o prova prova.o

(che produce il modulo eseguibile in prova).

5. Attivare il GDB con il comando: xscale-elf-gdb prova

6. Utilizzare l’interfaccia grafica (Source window: File → Target settings) per impostare: Target: Remote/Serial; Baud rate: 115200; port: COM1); poi (sour-ce window: Run → Connect to target).

7. Sempre sulla Source window: selezionare prova.s dal menu a discesa sulla sini-stra e impostare almeno un breakpoint (sulla prima istruzione del programma, sull’ultima e nei punti intermedi di interesse) facendo click con il mouse sul cor-rispondente trattino a sinistra delle istruzioni stesse.

8. Sempre sulla Source window: selezionare il comando Run (tramite l’apposita ico-na oppure Run → Run).

9. Si usano i pulsanti della Source windows per controllare l’esecuzione del codice.

USO DEL SIMULATORE: se si intende usare il simulatore (modalità Stand-alone simulator del gdb), si può ignorare il precedente punto 2 e, al punto 6, ci si limita ad impostare (Source window: File → Target settings) Target: Simulator. Tutti gli altri punti rimangono invariati.

Page 53: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

53

CAPITOLO V

Esercizi

5.1 Primo programma (somma di due numeri)

Conviene iniziare con un primo semplice programma in linguaggio assembly, che calcola la somma di due numeri: 1 /*add1.s**************************************************** 2 * somma di due numeri : * 3 * addendi immediati, risultato su registro * 4 ***********************************************************/ 5 6 .text 7 .global _start 8 9 _start: 10 mov r0, #10 @ carica il primo operando 11 mov r1, #15 @ carica il secondo operando 12 add r2, r1, r0 @ esegue la somma 13 _end: b _end @ trappola 14 15 .end 16 17 /**********************************************************/ 18 /* Suggerimento/variante: */ 19 /* in esecuzione passo-passo cambiare il valore contenuto */ 20 /* nei registri r0, r1 prima di eseguire la somma */ 21 /**********************************************************/

5.1.1 Il codice

Si esaminano, prima di tutto, le linee di testo che non contengono istruzioni eseguibili.

Le linee di testa (1-4) e di coda (17-21) sono commenti. L'assemblatore GNU per ARM supporta due tipi di commenti: quelli in stile linguaggio C, che cominciano con /* e terminano con */ e possono essere composti da più righe, come nel primo blocco in cui le righe da 1 a 4 sono un unico commento, oppure come nel blocco di coda, che è costi-tuito da cinque linee ognuna delle quali è costituita da un commento aperto e chiuso; un

Page 54: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

54

secondo modo in cui è possibile inserire dei commenti nel codice, tipico della program-mazione in linguaggio assembly, prevede di iniziare il commento con il carattere @: tut-ti i caratteri successivi, fino alla fine della riga corrente, verranno trattati come commento; un esempio sono le righe 10, 11, 12.

Alcune righe di testo contengono direttive, caratterizzate dal fatto che di solito co-minciano con un punto. Si ricorda che le direttive sono istruzioni particolari in quanto specificano comandi destinati ad essere eseguiti dall’assemblatore, nella fase di tra-duzione in linguaggio macchina (modulo oggetto) delle istruzioni assembly simboliche (modulo sorgente); ciò contraddistingue le direttive dalle altre istruzioni assembly, che specificano invece operazioni destinate ad essere eseguite, dal processore, nella fase di esecuzione del programma.

La prima direttiva che si incontra, alla riga 6, è .text: il suo effetto è di indicare (all’assemblatore) che le istruzioni che seguono andranno a far parte del segmento text del programma finale; nel segmento text di norma sono situate le istruzioni de-stinate ad essere eseguite dal processore.

Alla riga successiva si trova la direttiva .global: lo scopo di questa direttiva è di da-re visibilità globale, al di fuori del modulo corrente, ad uno o più simboli. Questa in-formazione è utilizzata nella fase di linking per risolvere i riferimenti tra i simboli de-finiti e usati in moduli diversi. Si vedrà più avanti il perché sia necessario definire glo-bale il simbolo _start.

Ultima direttiva presente è .end alla riga 15: indica semplicemente la fine del file as-sembly; tutto ciò che segue non è più elaborato dall'assemblatore, anche se si tratta di codice.

Un particolare tipo di direttiva è costituito dai label, definiti da simboli seguiti da un due punti ':' (non sono permessi spazi tra il simbolo e i due punti). Una direttiva label associa al simbolo il valore del location counter (si ricorda che il location counter è una variabile, interna all'assemblatore, nella quale l’assemblatore, durante la scansione del modulo sorgente, mantiene l’indirizzo di memoria in cui verrà collocata la prossima i-struzione di macchina che verrà generata). I simboli definiti da label sono spesso usa-ti come operandi per indicare, in modo simbolico, gli indirizzi all’interno di un pro-gramma.

Il resto del codice è molto semplice: le istruzioni alle linee 10 e 11 specificano il cari-camento di due valori immediati nei registri r0 e r1; l’istruzione alla linea 12 provoca il calcolo della somma di quei due valori (r1 + r0) e il suo caricamento in r2. L'ultima riga di codice effettivo è una trappola: infatti contiene una istruzione di salto incondizio-nato alla istruzione stessa; per cui il processore, quando arriva ad eseguirla, continue-rà ad eseguirla indefinitamente (se non lo si interrompe).

Page 55: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

55

5.1.2 Compilazione

Per ottenere un programma eseguibile partendo dai sorgenti in assembly, sono neces-sari due passaggi: prima creare, tramite l'assemblatore, un file contenente il modulo oggetto (.o) e successivamente, tramite il linker, dal modulo oggetto ottenere il pro-gramma eseguibile.

Posto che le istruzioni assembly (modulo sorgente) siano contenute nel file add1.s, il comando per l'invocazione dell'assemblatore è: xscale-elf-as -gstabs -o add1.o add1.s

All'assemblatore vengono passati tre parametri:

-gstabs: specifica che si vogliono includere, nel modulo oggetto, informazioni di debug (utili per le operazioni che si possono eseguire con il debugger), -o <file>.o: specifica il file di output (in cui verrà prodotto il modulo oggetto), <file>.s: specifica il file di input (contenente il modulo sorgente da tradurre).

L'invocazione del linker avviene con il comando: xscale-elf-ld -Ttext 0x00100000 -o add1 add1.o

Anche qui sono presenti tre parametri: -Ttext 0x00100000 per specificare l’indirizzo di memoria a partire dal quale si vuole che venga caricato il segmento text e, come per l'assemblatore, il file di output (add1) e quello di input (add1.o).

5.1.3 Debugging

Per invocare il debugger si usa il comando: xscale-elf-gdb add1

Per verificare il corretto funzionamento del programma, si possono eseguire le istru-zioni ad una ad una (modalità step) fino ad arrivare a quella situata alla riga 13 (oppure collocare un breakpoint su quest’ultima) e constatare che nel registro r2 viene pro-dotta la somma (25, ovvero 0x19) dei due operandi.

In questo semplice programma, ad ogni esecuzione viene calcolata la somma degli stes-si addendi ottenendo sempre lo stesso risultato. È possibile però utilizzare lo stesso modulo eseguibile per calcolare altre somme, utilizzando alcune delle possibilità ag-giuntive che il debugger mette a disposizione: eseguendo le istruzioni con modalità step (oppure definendo un breakpoint), si arrivi ad avere evidenziata la riga 12 del co-dice, ovvero quella con l'istruzione add. In questa situazione l’istruzione evidenziata deve essere ancora eseguita. Operando sulla finestra dei registri è possibile modifica-re il contenuto dei registri r0 e r1, (facendo clic con il mouse sul valore del registro, se ne può modificare il contenuto), ad esempio 0x12 e 0x23. Tornando sulla finestra principale ed avanzando di un altro passo l'esecuzione, il risultato nel registro r2 non è più 25 ma 53.

Page 56: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

56

5.2 Secondo programma (somma di due numeri)

1 /*add2.s***************************************************/ 2 /* somma di due numeri */ 3 /* addendi in memoria, risultato su registro */ 4 /**********************************************************/ 5 .text 6 .global _start 7 8 _start: 9 ldr r9, =in1 @ indirizzo del primo operando 10 ldr r0, [r9] @ carica in r0 il primo operando 11 ldr r9, =in2 @ indirizzo del secondo operando 12 ldr r1, [r9] @ carica in r1 il secondo operando 13 add r2, r1, r0 @ esegue la somma 14 _end: b _end @ trappola 15 16 .data 17 in1: .long 0x00000012 @ primo operando 18 in2: .long 0x00000034 @ secondo operando 19 20 .end

5.2.1 Il codice

Il secondo semplice programma è una evoluzione del precedente; la differenza consiste nel fatto che i valori degli addendi vengono caricati dalla memoria anziché essere definiti come operandi immediati.

Per caricare in un registro un valore contenuto in memoria bisogna procedere in due passi: prima caricare in un registro l’indirizzo della locazione di memoria e poi caricarne in un registro il contenuto con un'istruzione del tipo ldr Rn, [Rm]. Viste anche le limitazioni presenti negli indirizzamenti immediati non è di norma possibile caricare un indirizzo in un registro tramite una istruzione del tipo mov Rn, #imm. A questo scopo conviene utilizzare la pseudo-istruzione (o meglio lo pseudo-indirizzamento) ldr Rn, =imm nella quale spesso l’operando immediato è un simbolo definito come label.

Oltre alla pseudo-istruzione appena vista, nel codice sono presenti anche due nuove direttive: .data e .long. La prima (.data) serve a specificare l'utilizzo, da quella riga del programma in poi, del segmento data: tutto quello che verrà generato dalle righe successive (si tratterà ovviamente di dati) verrà collocato nel segmento data. La direttiva .long riserva uno spazio di 4 byte (un long word) in memoria e lo inizializza con il valore specificato. Nell’esempio, usando questa direttiva, è stato definito lo spazio in memoria per i due addendi e se ne sono definiti anche i valori (0x12 e 0x34).

Page 57: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

57

5.2.2 Compilazione

Posto di aver salvato il codice sorgente nel file add2.s, i comandi sono gli stessi dell’esempioo precedente, cambiando ovviamente i nomi dei file: xscale-elf-as -gstabs -o add2.o add2.s xscale-elf-ld -Ttext 0x00100000 -o add2 add2.o

5.2.3 Debugging

Per mandare in esecuzione il programma, i passi da seguire sono gli stessi dell'esempio precedente.

In questo secondo esempio gli addendi si trovano in memoria ed è interessante vedere come il debugger gdb consenta di modificare il contenuto delle locazioni di memoria: con il programma in esecuzione e bloccato (ad esempio con un breakpoint) alla prima istruzione, si apra la finestra di visualizzazione della memoria (menu: View->Memory); si prosegua poi l’esecuzione della sola istruzione alla riga 9 del programma, in modo da ottenere, nel registro r9, l'indirizzo di memoria corrispondente al label in1; si inseri-sca poi questo indirizzo nel campo 'Address' della finestra della memoria; in questa situazione il primo word di memoria visualizzato è quello corrispondente al label in1 e il secondo è quello relativo a in2 (nel programma sorgente i 2 word sono stati posti in posizioni consecutive); con modalità analoghe a quelle utilizzate per modificare il con-tenuto dei registri, è ora possibile modificare il contenuto della memoria.

NOTA: Ad ogni caricamento del programma tutte le zone di memoria di competenza del programma vengono reinizializzate, per cui le modifiche fatte “manualmente”, con le modalità descritte sopra, vengono perse, anche senza essere usciti dal debugger.

Page 58: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

58

5.3 Terzo programma (somma di due numeri)

Si procede con un terzo semplice esempio, relativo ancora alla somma di due numeri, questa volta prevedendo che anche il risultato venga collocato in memoria.

1 /*add3.s***************************************************/ 2 /* somma di due numeri */ 3 /* addendi in memoria, risultato in memoria */ 4 /**********************************************************/ 5 .text 6 .global _start 7 8 _start: 9 ldr r9, =in1 @ indirizzo del primo operando 10 ldr r0, [r9] @ carica in r0 il primo operando 11 ldr r9, =in2 @ indirizzo del secondo operando 12 ldr r1, [r9] @ carica in r1 il secondo operando 13 add r0, r0, r1 @ esegue la somma 14 ldr r9, =out @ indirizzo del risultato 15 str r0, [r9] @ memorizza il risultato 16 _end: b _end @ trappola 17 18 .data 19 in1: .long 0x00000012 @ primo operando 20 in2: .long 0x00000034 @ secondo operando 21 22 .bss 23 .align 4 24 out: .space 4 @ spazio per il risultato 25 .end

5.3.1 Il codice

Il risultato della operazione di somma viene memorizzato non nel segmento data, ma nel segmento bss, che è destinato a contenere, appunto, dati non inizializzati (cioè dati che, a differenza di quelli del segmento data, non hanno un valore assegnato quando il programma viene caricato in memoria; questi dati assumeranno dei valori solo durante l’esecuzione del programma, in seguito ad operazioni di scrittura).

La direttiva .bss indica l'utilizzo del segmento bss per cui il successivo label out individua un indirizzo situato in tale segmento.

La direttiva .space serve per riservare dello spazio libero (non inizializzato) nel segmento bss; l’argomento della direttiva (4 nell’esempio) indica l’estensione, in byte, dello spazio da riservare.

La direttiva .align 4 serve ad allineare l’indirizzo di memoria ad un valore multiplo di 4, in modo da consentire l’accesso corretto ai word (4 byte) collocati a partire da quell’indirizzo.

Page 59: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

59

5.3.2 Compilazione

Avendo salvato il codice sorgente nel file add3.s, i comandi sono gli stessi dell’esempio precedente cambiando solo, come ovvio, i nomi dei file: xscale-elf-as -gstabs -o add3.o add3.s xscale-elf-ld -Ttext 0x00100000 -o add3 add3.o

5.3.3 Debugging

Per questo terzo esempio ci si può limitare a controllare solo se il risultato viene scritto correttamente. Secondo le indicazioni dell'esempio precedente, per conoscere l'indirizzo corrispondente al label out, si dovrebbe arrivare ad eseguire l’istruzione alla linea 14; ma non sempre questo è accettabile: se è necessario conoscere fin dall'inizio l'indirizzo di memoria corrispondente ad un label si può utilizzare un altro dei tool disponibili nell’ambiente di sviluppo: 'nm'. Tramite il comando: xscale-elf-nm add3

è possibile ottenere l'indirizzo corrispondente a tutti i simboli definiti come label all'interno del modulo contenuto nel file specificato, tipicamente un modulo oggetto o un modulo eseguibile. Il risultato ottenuto con quel comando è:

00100150 A __bss_end__ 00100134 A __bss_start 00100134 A __bss_start__ 0010012c D __data_start 00100150 A __end__ 00100150 A _bss_end__ 00100134 A _edata 0010001c t _end 00100150 A _end 00080000 ? _stack 00100000 T _start 0010012c d in1 00100130 d in2 00100140 b out

la prima colonna indica l'indirizzo (in esadecimale), la seconda, costituita da un solo carattere, il tipo di simbolo ed infine la terza il nome del simbolo. Una piccola legenda per i tipi di simbolo

a : simbolo corrispondente ad un indirizzo assoluto d : simbolo corrispondente ad un indirizzo situato nel segmento data t : simbolo corrispondente ad un indirizzo situato nel segmento text b : simbolo corrispondente ad un indirizzo situato nel segmento bss

con le lettere maiuscole (A, D, T, B) vengono contrassegnati i simboli che hanno visibilità globale; le lettere minuscole si riferiscono, invece, a simboli locali.

Il simbolo out corrisponde all’indirizzo 0x100140, che si trova nel segmento bss. Questo è il valore da inserire come indirizzo nella finestra per il controllo della memoria nel debugger.

Page 60: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

60

5.4 Somma degli elementi di un vettore

Si prosegue ora con tre ulteriori esempi, leggermente più complessi dei precedenti, anche questi intesi a raggiungere il medesimo obiettivo, il calcolo della somma degli elementi di un vettore non vuoto di numeri interi naturali da 32 bit, ma realizzati in tre modi diversi. 1 /*sum1.s***************************************************/ 2 /* somma di un vettore di numeri */ 3 /**********************************************************/ 4 .text 5 .global _start 6 7 .equ elem, 10 @ numero di elementi del vettore 8 9 _start: 10 mov r0, #0 @ r0 conterrà la somma 11 ldr r9, =vec @ indirizzo del primo elemento 12 ldr r8, =elem @ contatore (da decrementare) 13 sub r8, r8, #1 @ indice dell’ultimo elemento 14 add r8, r9, r8, lsl #2 @ indirizzo dell’ultimo elem. 15 loop: ldr r1, [r9], #4 @ carica un elemento 16 add r0,r0,r1 @ lo somma in r0 17 cmp r8, r9 @ era l’ultimo? 18 bpl loop @ no: carica il prossimo 19 ldr r9, =out @ indirizzo del risultato 20 str r0, [r9] @ memorizza il risultato 21 _end: b _end @ trappola 22 23 .data 24 vec: .long 10,56,89,35,67,54,9,29,37,72 @ elementi 25 .bss 26 .align 4 27 out: .space 4 @ spazio per il risultato 28 .end

5.4.1 Il codice

Conviene chiarire dapprima lo scopo con cui vengono utilizzati i vari registri. r0: destinato a contenere la somma degli elementi del vettore r1: contiene, di volta in volta, il singolo elemento da sommare r8: contiene un puntatore all’ultimo elemento del vettore r9: contiene il puntatore all’elemento da sommare

Le righe dalla 10 alla 14 inizializzano i vari registri utilizzati: r0 viene azzerato; in r9 viene messo l'indirizzo del primo elemento del vettore; in r8 viene prima inserito il numero di elementi del vettore, poi viene decrementato in modo da ottenere l’indice dell'ultimo elemento (che è pari alla dimensione del vettore meno uno), infine questo indice viene trasformato in indirizzo, moltiplicandolo per 4 (lsl #2) poiché ogni ele-mento è di 4 byte e sommandolo poi all'indirizzo iniziale del vettore.

Page 61: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

61

Le righe da 15 a 18 costituiscono il ciclo (loop), che viene eseguito tante volte quanti sono gli elementi del vettore: ad ogni iterazione viene caricato in r1 l’elemento da sommare (il word puntato da r9), contestualmente r9, usato con post-incremento in-cremento immediato, viene incrementato di 4 e passa a puntare all’elemento successi-vo; il valore caricato in r1 viene aggiunto alla somma parziale in r0; dopo la verifica che r9 non abbia superato l’ultimo elemento del vettore, viene effettuata un'altra intera-zione.

Alla fine, il risultato viene salvato in memoria.

5.4.2 Compilazione

I comandi sono i soliti: xscale-elf-as -gstabs -o sum1.o sum1.s

xscale-elf-ld -Ttext 0x00100000 -o sum1 sum1.o

5.4.3 Debugging

Per questo esempio può essere interessante provare a modificare in memoria i valori degli elementi del vettore al fine di constatare la correttezza del programma.

Page 62: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

62

5.5 Somma degli elementi di un vettore (subroutine)

Lo stesso scopo dell’esempio precedente, il calcolo della somma degli elementi di un vettore, può essere ottenuto definendo una subroutine (una funzione), che presenta il vantaggio di poter essere facilmente riutilizzata da altri programmi. 1 /*sum2.s***************************************************/ 2 /* somma di un vettore di numeri */ 3 /**********************************************************/ 4 .text 5 .global _start 6 7 .equ elem, 10 @ numero di elementi del vettore 8 9 _start: 10 ldr sp, =stack @ inizializza lo stack pointer 11 ldr r2, =elem @ numero di elementi 12 ldr r1, =vec @ indirizzo del primo elemento 13 bl somma @ chiama la subroutine somma 14 ldr r9, =out @ indirizzo del risultato 15 str r0, [r9] @ memorizza il risultato 16 _end: b _end @ trappola 17 18 .func somma 19 /*--------------------------------------------------------*/ 20 /* calcola la somma degli elementi di un vettore */ 21 /* input: */ 22 /* R1: indirizzo del primo elemento del vettore */ 23 /* R2: numero di elementi del vettore */ 24 /* output: */ 25 /* R0: somma */ 26 /*--------------------------------------------------------*/ 27 somma: stmfd sp!, {r2,r3} @ salva nello stack i registri 28 bic r0, r0, r0 29 sub r2, r2, #1 @ indice dell’ultimo elemento 30 somma_l: ldr r3, [r1, r2, lsl #2] @ carica un elemento 31 add r0,r0,r3 @ lo somma in r0 32 subs r2, r2, #1 @ decrementa l’indice 33 bge somma_l @ se >=0, carica il prossimo 34 ldmfd sp!, {r2,r3} @ ripristina i registri salvati 35 mov pc, lr @ ritorna al programma chiamante 36 .endfunc 37 38 .data 39 vec: .long 1,2,3,4,5,6,7,8,9,10 @ elementi 40 41 .bss 42 .align 4 43 out: .space 4 @ spazio per il risultato 44 .space 4096 @ spazio per lo stack 45 stack: .space 4 @ base dello stack 46 47 .end

Page 63: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

63

5.5.1 Il codice

In questo esempio appaiono per la prima volta due elementi, lo stack e la chiamata a subroutine.

Con riferimento allo stack, si osserva che, essendo esso di tipo full-descending, le direttive che lo definiscono (nel segmento bss) comprendono un label (stack) che individua l’indirizzo successivo allo spazio di memoria riservato allo stack stesso (base dello stack), Nella riga 10 allo stack pointer viene assegnato il valore iniziale (quando uno stack full-descending è vuoto, lo stack pointer punta proprio all’indirizzo successivo all’area di memoria riservata allo stack).

La necessità di definire uno stack è legata al fatto che questo esempio comprende una subroutine e, come è noto, è buona disciplina di programmazione prevedere che ogni subroutine salvi all’inizio, con operazioni di push nello stack appunto, il contenuto dei registri che vengono da essa modificati (purché non contengano parametri di uscita, cioè valori restituiti dalla subroutine stessa) e che ne ripristini il contenuto, con altrettante operazioni di pop, prima di ritornare al programma chiamante.

Si può constatare che il corpo principale del programma, quello compreso tra i label _start e _end, è piuttosto semplice: le operazioni svolte sono solo l’inizializzazione dello stack pointer, l’inserimento nei registri r1 ed r2 dei parametri di ingresso alla subroutine somma, la chiamata della subroutine stessa e la memorizzazione del risultato da essa restituito in r0.

Si segnala l’importanza delle righe da 19 a 26 che contengono, sotto forma di commento, le informazioni che specificano l'interfaccia della subroutine: la funzione che essa realizza, i parametri di ingresso, quelli di uscita e quali registri vengono eventualmente da essa modificati. L’interfaccia di una subroutine contiene le informazioni che devono essere note al programmatore che intende utilizzare la subroutine stessa.

Nel codice sono presenti due nuove direttive per l'assemblatore (.func e .endfunc), le quali servono a delimitare il codice appartenente ad una funzione. Non sono necessarie per la definizione di una subroutine, ma sono utili in fase di debugging per isolare il codice delle varie routine presenti nel programma.

La subroutine somma è organizzata in modo abbastanza simile al codice dell'esempio precedente: all’interno di un ciclo, ad ogni iterazione, un nuovo elemento viene aggiunto alla somma parziale contenuta in r0; a differenza dell’esempio precedente, però, ora gli elementi vengono scanditi dall'ultimo al primo (sono individuati dall’indice contenuto in r2, che viene decrementato ad ogni iterazione), e l’istruzione ldr alla riga 30 non usa metodi di indirizzamento che modificano i registri coinvolti. Nell’istruzione che decrementa l’indice, alla riga 32, viene usato il suffisso 'S' che abilita la modifica dei bit di condizione nel registro di stato (CPSR): ciò consente di risparmiare l’uso di un’istruzione di confronto per stabilire quando terminare le iterazioni.

Page 64: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

64

Il ritorno al programma chiamante, dopo che r0 contiene la somma richiesta e dopo aver ripristinato i valori originari di r2 ed r3, viene ottenuto con l’istruzione alla riga 35, che rimette in pc il valore che era stato salvato in lr dall’istruzione di chiamata (riga 13),

Si noti che i registri r2 ed r3, che subiscono modifiche nel corso della esecuzione della subroutine, vengono salvati nello stack all’inizio e ripristinati alla fine della subroutine, mentre r1, che non viene modificato, non necessita di venir salvato.

5.5.2 Compilazione

I comandi sono i soliti: xscale-elf-as -gstabs -o sum2.o sum2.s

xscale-elf-ld -Ttext 0x00100000 -o sum2 sum2.o

5.5.3 Debugging

Si suggerisce di verificare, con il debugger gdb, sia le variazioni dei valori contenuti nei registri lr, pc ed sp in corrispondenza, rispettivamente, delle istruzioni di chiamata a subroutine (riga 13), di ritorno dalla subroutine (riga 35) e delle istruzioni di push (riga 27) e pop (riga 34).

Inoltre anche per questo esempio può essere interessante provare a modificare in memoria i valori degli elementi del vettore al fine di constatare la correttezza del programma.

Page 65: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

65

5.6 Somma degli elementi di un vettore (subroutine ricorsiva)

Lo stesso esempio che calcola la somma degli elementi di un vettore può essere realizzato anche tramite un algoritmo ricorsivo, ottenuto con una subroutine che prevede di richiamare se stessa. 1 /*sum3.s***************************************************/ 2 /* somma di un vettore di numeri */ 3 /**********************************************************/ 4 .text 5 .global _start 6 7 .equ elem, 10 @ numero di elementi del vettore 8 9 _start: 10 ldr sp, =stack @ inizializza lo stack pointer 11 ldr r2, =elem @ numero di elementi 12 ldr r1, =vec @ indirizzo del primo elemento 13 bl somma @ chiama la subroutine somma 14 ldr r9, =out @ indirizzo del risultato 15 str r0, [r9] @ memorizza il risultato 16 _end: b _end @ trappola 17 18 .func somma 19 /*--------------------------------------------------------*/ 20 /* funzione ricorsiva per la somma degli el. di un vettore*/ 21 /* input: */ 22 /* R1: indirizzo del primo elemento del vettore */ 23 /* R2: numero di elementi del vettore */ 24 /* output: */ 25 /* R0: somma */ 26 /*--------------------------------------------------------*/ 27 somma: stmfd sp!, {r1-r3,lr} @ salva i registri (anche lr) 28 cmp r2, #1 @ c’è un solo elemento? 29 bhi somma_split @ no: procede con l’algoritmo 30 ldr r0, [r1] @ si: la somma è l’elemento e ... 31 b somma_end @ la subr. termina restituendolo 32 somma_split: @ divide a metà il vettore 33 mov r3, r2, lsr #1 @ n. di elem. della seconda metà 34 sub r2, r2, r3 @ n. di elem. della prima metà 35 bl somma @ somma della prima metà in r0 36 add r1, r1, r2, lsl #2 @ indirizzo della seconda metà 37 mov r2, r3 @ n. di elem. della seconda metà 38 mov r3, r0 @ in r3 la somma della prima metà 39 bl somma @ somma della seconda metà in r0 40 add r0, r0, r3 @ somma delle due metà 41 somma_end: 42 ldmfd sp!, {r1-r3,pc} @ ripristina i registri (lr->pc) 43 .endfunc 44 45 .data 46 vec: .long 1,2,3,4,5,6,7,8,9,10 @ elementi 47 48 .bss 49 .align 4

Page 66: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

66

50 out: .space 4 @ spazio per il risultato 51 .space 4096 @ spazio per lo stack 52 stack: .space 4 @ base dello stack 53 .end

5.6.1 Il codice

La subroutine somma ha la stessa interfaccia della omonima subroutine dell’esempio precedente, ma, come si può constatare, l’organizzazione del codice è completamente diversa. L'idea alla base dell'algoritmo è di spezzare in due il vettore, calcolare le somme degli elementi di ciascuna delle due metà e sommarle tra loro per ottenere la somma dell'intero vettore. Allo stesso modo (ricorsivamente) si procede per calcolare la somma di ciascuna metà e così via, ricorsivamente, fino ad ottenere vettori di un solo elemento il cui valore coincide con la somma del vettore.

Per prima cosa (riga 27) la subroutine provvede a salvare nello stack i registri (diversi da r0, in cui viene restituito il parametro di uscita) che vengono modificati nel corso della propria esecuzione. Si osservi che la subroutine contiene istruzioni di chiamata a subroutine, le quali modificano il registro lr (link register): per questo motivo è necessario che lr, che contiene l’indirizzo di ritorno dalla subroutine, sia incluso nella lista dei registri da salvare nello stack.

Le righe (28..31) della subroutine verificano se il vettore è costituito da un solo elemento, nel qual caso il valore dell’elemento viene restituito in r0 come risultato, altrimenti si procede a spezzare in due il vettore e a richiamare ricorsivamente la subroutine somma stessa (due volte, una per ciascuna metà del vettore).

A questo scopo vengono dapprima calcolate le lunghezze (il numero di elementi) di ciascuna delle due parti del vettore (attenzione: se il vettore originario ha un numero di elementi dispari, le due parti non hanno la stessa lunghezza); le due lunghezze vengono messe in r2 e r3 (righe 33 e 34). In r1 e r2 vi sono ora i parametri da passare alla stessa subroutine somma, che viene chiamata (riga 35) per calcolare la somma degli elementi della prima metà del vettore; successivamente in r1 e r2 vengono messi i parametri (indirizzo del primo elemento e numero di elementi) relativi alla seconda parte del vettore (righe 36 e 37) per la seconda chiamata alla subroutine somma (riga 39); per ottenere l’indirizzo del primo elemento della seconda parte, all’indirizzo iniziale del vettore, contenuto in r1, viene sommato la lunghezza della prima metà moltiplicata per 4 poiché gli elementi sono da 4 byte; prima della seconda chiamata alla subroutine somma (che restituirà in r0 la seconda somma), la prima somma viene spostata da r0 ad r3, altrimenti verrebbe sovrascritta. Al ritorno dalla seconda chiamata, in r3 e in r0 vi sono le somme delle due parti, sommando le quali (riga 40) si ottiene la somma complessiva da restituire in r0.

Si osservi che le operazioni di ripristino degli altri registri modificati e di ritorno al programma chiamante sono ottenute con un’unica istruzione (riga 42) con la quale il valore di lr precedentemente salvato nello stack viene caricato nel pc.

Page 67: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

67

5.6.2 Compilazione

I comandi sono i soliti: xscale-elf-as -gstabs -o sum3.o sum3.s

xscale-elf-ld -Ttext 0x00100000 -o sum3 sum3.o

Page 68: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

68

5.7 Rovesciamento di una stringa di caratteri

Questo esempio presenta una subroutine che opera il rovesciamento di una stringa di caratteri. L’esempio fornisce l’occasione per vedere come sia possibile usare lo stack (con operazioni di push e di pop) come area di lavoro (per collocarvi dati locali alla subroutine stessa). 1 /*strrev.s*************************************************/ 2 /* rovesciamento di una stringa di caratteri */ 3 /**********************************************************/ 4 .text 5 .global _start 6 7 8 _start: 9 ldr sp, =stack @ inizializza lo stack pointer 10 ldr r1, =str @ indirizzo del primo elemento 11 bl strrev @ chiama la subroutine strrev 12 _end: b _end @ trappola 13 14 .func strrev 15 /*--------------------------------------------------------*/ 16 /* funzione che rovescia una stringa: la stringa sia in */ 17 /* input che output è terminata da un byte nullo:"\0"(EOS)*/ 18 /* input/output: */ 19 /* R1: indirizzo primo carattere della stringa */ 20 /*--------------------------------------------------------*/ 21 strrev: 22 stmfd sp!,{r0-r3,lr} @ salva i registri (anche lr) 23 mov r3, r1 @ salva l’indirizzo della stringa 24 mov r2, sp @ salva sp 25 strrev_l: 26 ldrb r0, [r1], #+1 @ preleva un carattere, post-inc 27 strb r0, [sp, #-1]! @ lo inserisce nello stack, pre-dec 28 tst r0,#0xff @ si tratta di EOS? 29 bne strrev_l @ no: preleva il car. successivo 30 mov r1,r3 @ si: ripristina r1 (ind. stringa) 31 add sp,sp, #1 @ elimina dallo stack l’EOS 32 strrev_l2: 33 ldrb r0, [sp], #+1 @ pop un car. dallo stack, post-inc 34 strb r0, [r1], #+1 @ lo inserisce nella str., post-inc 35 cmp sp,r2 @ sp è tornato al val. originario? 36 blo strrev_l2 @ no: pop dallo stack il prossimo 37 ldmfd sp!,{r0-r3,pc} @ ripristina i registri (lr->pc) 38 /*--------------------------------------------------------*/ 39 .endfunc 40 41 .data 42 str: .ascii "Architettura degli elaboratori \0" 43 .bss 44 .align 4 45 .space 4096 @ spazio per lo stack 46 stack: .space 4 @ base dello stack 47 .end

Page 69: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

69

5.7.1 Il codice

La subroutine strrev opera il rovesciamento di una stringa inserendone dapprima i caratteri (escluso l’ultimo EOS), ad uno ad uno, nello stack con operazioni di push: essendo lo stack di tipo full-descending, in questo modo in cima allo stack, puntata da sp, si troverà la stringa rovesciata; successivamente i caratteri di questa stringa vengono estratti dallo stack, con operazioni di pop, e collocati (dall'ultimo al primo) al posto della stringa di input, sovrascrivendola (EOS rimane al suo posto).

Alle righe 23 e 24 vengono salvati in altri due registri i valori iniziali di r1 e dello stack pointer (sp), perché serviranno più avanti; nel loop dalla riga 25 alla 29, viene effettuato il push sullo stack, ad uno ad uno, dei successivi caratteri della stringa, fino a che non viene incontrato il carattere 0x00 ovvero '\0', che segnala la fine della stringa (EOS); viene poi ripristinato r1 al valore iniziale (indirizzo della stringa) e viene incrementato lo sp in modo da eliminare dallo stack l’ultimo carattere inserito (EOS) che non va copiato come primo carattere della stringa e che si trova già al suo posto nella stringa; nel loop dalla riga 32 alla 36, i caratteri della stringa vengono estratti dallo stack e inseriti al posto della stringa di input in ordine opposto a quello con cui erano stati inseriti, dall’ultimo al primo, in modo da ottenere la stringa rovesciata. Il ciclo termina quando sp torna ad avere lo stesso valore che aveva all'inizio della subroutine.

L’uso dello stack fatto in questo esempio, seppur corretto, non è consigliato in quando inserendo nello stack un byte alla volta, lo stack pointer può assumere anche valori dispari o comunque non multipli di 4: ciò impedirebbe di operare correttamente il push sullo stack di un word (4 byte), in quanto i word in memoria possono essere collocati solo ad indirizzi che siano multipli di 4. Conviene quindi che lo stack pointer sia sempre allineato ad indirizzi multipli di 4.

5.7.2 Compilazione

I comandi sono i soliti: xscale-elf-as -gstabs -o strrev.o strrev.s

xscale-elf-ld -Ttext 0x00100000 -o strrev strrev.o

5.7.3 Debugging

Per verificare la correttezza del programma conviene utilizzare due finestre per monitorare la memoria: una in cui sia visualizzato lo spazio nel segmento dati occupato dalla stringa iniziale (e che conterrà anche la stringa rovesciata alla fine dell'esecuzione); una seconda in cui sia visualizzato il contenuto dello stack utilizzato come area di lavoro per collocarvi i caratteri della stringa.

Per mettere in evidenza il problema dell'allineamento, si può inserire tra le righe 31 e

Page 70: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

70

32 due operazioni inutili come stmfd sp!,{r0}

ldmfd sp!,{r0}

che effettuano il push sullo stack e, subito dopo, il pop del word (4 byte) contenuto nel registro r0.

Eseguendo sulla scheda UNI-PD-PXA il programma modificato in questo modo, si verificherà un errore (eccezione SIGBUS) a seguito dell'esecuzione della stmfd, dovuta al fatto che lo sp ha un valore non multiplo di 4; eseguendo il programma sul simulatore, invece, il problema non viene rilevato (ciò conferma che l’esecuzione tramite simulatore non rispecchia completamente quanto avviene con l’esecuzione “vera” da parte del processore).

Page 71: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

71

5.8 Rovesciamento di una stringa di caratteri (con sp allineato)

Si presenta ora una seconda versione del programma che opera il rovesciamento di una stringa di caratteri.

Il codice che segue elimina il problema riscontrato nella versione precedente, mantenendo allineato ad un multiplo di 4 l'indirizzo contenuto nello stack pointer. 1 /*strrev2.s************************************************/ 2 /* rovesciamento di una stringa di caratteri */ 3 /**********************************************************/ 4 .text 5 .global _start 6 7 8 _start: 9 ldr sp, =stack @ inizializza lo stack pointer 10 ldr r1, =str @ indirizzo del primo elemento 11 bl strrev @ chiama la subroutine strrev 12 _end: b _end @ trappola 13 14 .func strrev 15 /*--------------------------------------------------------*/ 16 /* funzione che rovescia una stringa: la stringa sia in */ 17 /* input che output è terminata da un byte nullo:"\0"(EOS)*/ 18 /* input/output: */ 19 /* R1: indirizzo primo carattere della stringa */ 20 /*--------------------------------------------------------*/ 21 strrev: 22 stmfd sp!,{r0-r4,lr} @ salva i registri (anche lr) 23 mov r2, r1 @ in r2 l’indirizzo della stringa 24 strrev_l0: 25 ldrb r0, [r2], #+1 @ preleva un carattere, post-inc 26 tst r0, #0xff @ si tratta di EOS? 27 bne strrev_l0 @ no: preleva il car. successivo 28 sub r2, r2, r1 @ si: in r2 n. car. str. (con EOS) 29 bic r4, r2, #3 @ azzera i bit 0 ed 1 30 cmp r2, r4 @ se uguali: r2 è un multiplo di 4 31 addne r4, r4, #4 @ se no: in r4 il mult. successivo 32 mov r3, sp @ in r3 lo sp 33 sub sp, sp, r4 @ alloca area riservata sullo stack 34 @ r3 punta alla base di quest’area 35 @ sp rimane allineato a mult. di 4 36 37 strrev_l1: 38 ldrb r0, [r1], #+1 @ preleva un carattere, post-inc 39 strb r0, [r3, #-1]! @ lo inserisce nello stack, pre-dec 40 tst r0, #0xff @ si tratta di EOS? 41 bne strrev_l1 @ no: preleva il car. successivo 42 add r3, r3, #1 @ elimina l’EOS 43 sub r1, r1, r2 @ r1 punta di nuovo al primo car. 44 sub r2, r2, #1 @ n. di car. da copiare (senza EOS) 45 strrev_l2: 46 ldrb r0, [r3], #+1 @ preleva car. da stack, post-inc

Page 72: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

72

47 strb r0, [r1], #+1 @ lo inserisce nella str., post-inc 48 subs r2, r2, #1 @ decrementa il contatore di car. 49 bne strrev_l2 @ preleva il prossimo se cont ≠ 0 50 add sp, sp, r4 @ rimuove l’area dallo stack 51 ldmfd sp!,{r0-r4,pc} @ ripristina i registri (lr->pc) 52 /*--------------------------------------------------------*/ 53 .endfunc 54 55 .data 56 str: .ascii "Architettura degli elaboratori \0" 57 .bss 58 .align 4 59 .space 4096 @ spazio per lo stack 60 stack: .space 4 @ base dello stack 61 .end

5.8.1 Il codice

Rispetto alla versione del paragrafo precedente, la subroutine dapprima calcola, in r2, la lunghezza della stringa, (righe 25-28); viene poi calcolata, in r4, la lunghezza dello spazio da riservare sullo stack in modo che sia un multiplo di 4 byte (righe 29-31): r4 rimane uguale ad r2 se questo è multiplo di 4, altrimenti viene posto uguale al multiplo di 4 immediatamente superiore; viene quindi allocato sullo stack tale spazio sottraendo da sp la linghezza calcolata in r4 (riga 33).

Per il resto l’organizzazione del codice è simile a quella della versione precedente.

5.8.2 Compilazione

I comandi sono i soliti: xscale-elf-as -gstabs -o strrev2.o strrev2.s

xscale-elf-ld -Ttext 0x00100000 -o strrev2 strrev2.o

5.8.3 Debugging

Come per l'esercizio precedente, si suggerisce di utilizzare due finestre per il monitoraggio della memoria.

Si può anche verificare che adesso l’inserzione delle istruzioni di push e pop di un word non provoca problemi.

Page 73: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

73

5.9 Ordinamento di un vettore (merge-sort)

In questo esempio viene presentata la realizzazione, in linguaggio assembly, dell'algoritmo di merge-sort per ordinare gli elementi di un vettore: si farà uso di 2 subroutine: la prima (sort) ricorsiva che ordina le due metà del vettore; la seconda (merge) che fonde in un unico vettore ordinato due vettori già ordinati.

L’esempio prevede che gli elementi dei vettori da ordinare siano numeri naturali della dimensione di un singolo byte. 1 /*msort_b.s************************************************/ 2 /* merge-sort di un vettore di naturali (da un byte) */ 3 /**********************************************************/ 4 .text 5 .global _start 6 7 .equ elem, 10 @ numero di elementi del vettore 8 9 _start: 10 11 ldr sp, =stack @ inizializza lo stack pointer 12 13 ldr r1, =vec @ indirizzo del vettore 14 ldr r2, =elem @ numero di elementi del vettore 15 bl sort @ chiama la subroutine sort 16 _end: b _end @ trappola 17 18 19 .func sort 20 /*--------------------------------------------------------*/ 21 /* funzione che ordina i componenti di un vettore */ 22 /* input/output: */ 23 /* R1: indirizzo del primo elemento del vettore */ 24 /* R2: lunghezza del vettore */ 25 /*--------------------------------------------------------*/ 26 sort: stmfd sp!, {r1-r6,lr} @ salva i registri (anche lr) 27 cmp r2, #1 @ c’è un solo elemento? 28 beq sort_end @ si: fine subr. (il vet. è ordinato) 29 sort_split: @ no: procede con l’algoritmo 30 @ r1,r2 indirizzo e lunghezza della prima metà del vettore 31 @ r3,r4 indirizzo e lunghezza della seconda metà del vettore 32 mov r4, r2 33 mov r2, r2, lsr #1 @ r2=r2/2 (n. el. della prima metà) 34 sub r4, r4, r2 @ n. di elementi della seconda metà 35 add r3, r1, r2 @ ind. del primo el. seconda metà 36 @ ordina la prima metà: 37 bl sort 38 mov r5, r1 @ salva r1, r2 in r5, r6 39 mov r6, r2 40 mov r1, r3 @ copia r3, r4 in r1, r2 41 mov r2, r4 42 @ ordina la seconda metà: 43 bl sort 44 mov r1, r5 @ ripristina r1, r2 (prima metà)

Page 74: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

74

45 mov r2, r6 46 @ fonde le due metà già ordinate 47 bl merge 48 sort_end: 49 ldmfd sp!, {r1-r6,pc} @ ripristina i registri (lr->pc) 50 /*--------------------------------------------------------*/ 51 .endfunc 52 53 .func merge 54 /*--------------------------------------------------------*/ 55 /* funzione che fa il merge di due vettori contigui gia` */ 56 /* ordinati mantenendo l'ordinamento */ 57 /* input: */ 58 /* R1: indirizzo del primo elemento del primo vettore */ 59 /* R2: lunghezza del primo vettore */ 60 /* R3: indirizzo del primo elemento del secondo vettore */ 61 /* R4: lunghezza del secondo vettore */ 62 /* output: */ 63 /* R1: indirizzo del primo elemento del vettore ordinato */ 64 /* R2: lunghezza del vettore ordinato */ 65 /*--------------------------------------------------------*/ 66 merge: 67 stmfd sp!,{r0-r7,lr} @ salva i registri (anche lr) 68 sub r0, sp, #1 @ r0: ind. primo byte sopra lo stack 69 add r7, r2, r4 @ lunghezza del vettore ordinato 70 sub sp, sp, r7 @ area di lavoro sullo stack 71 bic sp, sp, #3 @ allinea sp al multiplo di 4 72 @ immediatamente inferiore o uguale 73 sub r2, r2, #1 @ indice dell’ultimo el. del 1° vett. 74 sub r4, r4, #1 @ indice dell’ultimo el. del 2° vett. 75 ldrb r5, [r1, r2] @ preleva l’ultimo el. del 1° vett. 76 ldrb r6, [r3, r4] @ preleva l’ultimo el. del 2° vett. 77 merge_loop: 78 cmp r5, r6 @ confronta i due elementi prelevati 79 blo merge_v2 @ salta se r5 < r6 (cmp tra naturali) 80 merge_v1: @ copia nell’area di lavoro l’elemento del 1° vettore 81 strb r5, [r0], #-1 @ copia, post-dec 82 subs r2, r2, #1 @ indice el. precedente del 1° vett. 83 ldrgeb r5, [r1, r2] @ lo preleva, posto che ci sia 84 blt copy_v2 @ se non c’è, copia il resto del 2° 85 b merge_loop @ confrontalo con quello del 2° vet. 86 merge_v2: @ copia nell’area di lavoro l’elemento del 2° vettore 87 strb r6, [r0], #-1 @ copia, post-dec 88 subs r4, r4, #1 @ indice el. precedente del 2° vett. 89 ldrgeb r6, [r3, r4] @ lo preleva, posto che ci sia 90 blt copy_v1 @ se non c’è, copia il resto del 1° 91 b merge_loop @ confrontalo con quello del 1° vet. 92 copy_v1: @ copia nell’area di lavoro gli elementi restanti del 1° 93 strb r5, [r0], #-1 @ copia, post-dec 94 subs r2, r2, #1 @ indice el. precedente del 1° vett 95 ldrgeb r5, [r1, r2] @ lo preleva, posto che ci sia 96 bge copy_v1 @ se c’è, prova a copiarne un altro 97 b merge_end @ altrimenti il merge è finito 98 copy_v2: @ copia nell’area di lavoro gli elementi restanti del 2° 99 strb r6, [r0], #-1 @ copia, post-dec 100 subs r4, r4, #1 @ indice el. precedente del 2° vett 101 ldrgeb r6, [r3, r4] @ lo preleva, posto che ci sia

Page 75: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

75

102 bge copy_v2 @ se c’è, prova a copiarne un altro 103 b merge_end @ altrimenti il merge è finito 104 merge_end: @ ricopia il vett. ordinato al posto del vett. di input 105 add r2, r0, #1 @ r2 punta all’ultimo el. inserito 106 mov r3, #0 @ r3 è l’offset 107 mcopy_l: ldrb r0, [r2, r3] @ carica l’elem. dall’area di lavoro 108 strb r0, [r1, r3] @ lo ricopia nel vettore di input 109 add r3, r3, #1 @ incrementa l’offset 110 cmp r3, r7 @ ricopiato tutto? 111 blo mcopy_l @ no: ricopia il prossimo 112 add sp, sp, r7 @ si: rimuove l’area di lavoro 113 tst sp, #3 @ sp è allineato a multiplo di 4? 114 bicne sp, sp, #3 @ no: multiplo immediatamente infer. 115 addne sp, sp, #4 @ adesso è quello giusto 116 ldmfd sp!,{r0-r7,pc} @ ripristina i registri (lr->pc) 117 /*--------------------------------------------------------*/ 118 .endfunc 119 120 .data 121 vec: .byte 8,6,5,9,7,3,4,1,10,2 @ elementi 122 123 .bss 124 .align 4 125 .space 4096 @ spazio per lo stack 126 stack: .space 4 @ base dello stack 127 .end

5.9.1 Il codice

Il codice rispecchia la nota organizzazione dell'algoritmo di merge-sort: la prima par-te (subroutine sort), ricorsiva, dimezza il vettore fino ad arrivare a un vettore di un solo elemento e quindi già ordinato; la seconda parte (subroutine merge) effettua il merge di due vettori ordinati mantenendo l'ordinamento.

Si può constatare, nella subroutine merge, la particolare attenzione posta nell'alloca-re sullo stack l’area di lavoro mantenendo lo stack pointer allineato a multiplo di 4.

Sempre nella subroutine merge, i vettori vengono scanditi dall'ultimo elemento al pri-mo: i due elementi scanditi, uno del primo vettore e uno del secondo, vengono confron-tati (merge_loop) e, di volta in volta, viene copiato nell’area di lavoro il maggiore dei due, mantenendo l'ordinamento, (merge_v1 e merge_v2); quando poi uno dei due vet-tori è terminato, la rimanente parte dell'altro viene ricopiata senza ulteriori confron-ti, (copy_v1 e copy_v2).

Infine il vettore ordinato costruito nell’area di lavoro sullo stack, viene ricopiato nell’area di memoria che contiene i due vettori ricevuti in input; si osservi che ciò pre-suppone che i due vettori in input alla subroutine merge siano contigui in memoria: l'u-so della subroutine all'interno del sort garantisce il rispetto di questo requisito.

Page 76: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

76

5.9.2 Compilazione

I comandi sono i soliti: xscale-elf-as -gstabs -o msort_b.o msort_b.s

xscale-elf-ld -Ttext 0x00100000 -o msort_b msort_b.o

5.9.3 Debugging

Il debugging può essere complesso a causa dell'elevato numero di chiamate ricorsive: conviene esaminare la situazione del vettore parzialmente ordinato all'inizio della chiamata a merge ed eventualmente seguire solo alcune delle istanze in cui i vettori in input a merge hanno più di un elemento.

Si suggerisce anche per questo esempio di utilizzare due finestre per monitorare la memoria: una in cui sia visualizzato lo spazio nel segmento dati occupato dal vettore iniziale (e che conterrà il vettore ordinato alla fine dell'esecuzione); una seconda in cui sia visualizzato il contenuto dello stack utilizzato come area di lavoro.

Page 77: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

77

5.10 Il pannello frontale: i led e gli switch

Si esamina ora un semplice programma inteso ad illustrare l’uso di alcuni dispositivi presenti sul pannello frontale della scheda: i led e gli switch. 1 /*led1.s***************************************************/ 2 .include "front.inc" 3 .global _start 4 5 _start: 6 ldr sp, =stack @ inizializza lo stack pointer 7 bl init_front @ chiama la subroutine init_front 8 ldr r1,=LED_ADDR @ indirizzo dei led e degli switch 9 loop: ldrh r0, [r1] @ legge lo stato degli switch 10 strh r0, [r1] @ lo scrive sui led 11 b loop @ indefinitamente 12 _end: b _end @ trappola 13 14 .bss 15 .space 4096 @ spazio per lo stack 16 stack: .space 4 @ base dello stack 17 18 .end

5.10.1 Il codice

Conviene esaminare dapprima la nuova direttiva .include presente alla riga 2.

Essa è usata per includere il contenuto di un altro file sorgente in modo simile a quello che la direttiva #include fa per il linguaggio C/C++.

In un contesto di moduli sorgenti assembly, di norma, i file di tipo include (contenenti codice sorgente destinato ad essere incluso in altri file) hanno estensione .inc.

Nel caso in esame il file front.inc definisce alcuni simboli utili nell'utilizzo del pannello frontale. Ecco il contenuto del file : 1 /*front.inc*************************************************/ 2 LED_ADDR = 0x70000000 @ indirizzo dei led e switch (halfword) 3 BUT_ADDR = 0x40e00000 @ indirizzo dei pin GPIO 4 LEF_MASK = 0x00000800 @ bit corrispondente al pulsante sinistro 5 RIG_MASK = 0x00000400 @ bit corrispondente al pulsante destro 6 BUT_MASK = 0x00000C00 @ maschera per i bit di entrambi i puls.

Va precisato che l’indirizzo 0x70000000, associato al simbolo LED_ADDR (riga 2 di front.inc), individua un halfword (16 bit) sul quale sono mappati sia i 16 switch sia i 16 led presenti sul pannello frontale della scheda: con un’operazione di lettura si ottiene lo stato degli switch; con un’operazione di scrittura si imposta lo stato dei led.

L’indirizzo 0x40e00000, associato al simbolo BUT_ADDR (riga 3), individua un word sul quale sono mappati i pin GPIO: il bit di indice 11 di quel word (maschera 0x00000800)

Page 78: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

78

corrisponde al pulsante sinistro del pannello frontale; il bit di indice 10 (maschera 0x00000400) corrisponde al pulsante destro,

Tornando al codice presente nel file led1.s, dopo aver inizializzato lo stack (riga 6), viene chiamata la subroutine init_front (riga 7) la quale, come suggerisce il nome, provvede alle inizializzazioni necessarie per operare sui dispositivi del pannello frontale: non essendo presente nel modulo sorgente, si tratta di una subroutine esterna, definita in un altro modulo sorgente che dovrà essere collegata al modulo in esame ad opera del linker. Dopo aver caricato in r1 l'indirizzo dello halfword in cui sono mappati in memoria i led e gli switch (riga 8), viene eseguito un ciclo infinito nel quale viene ripetutamente letto lo stato degli switch (riga 9) e riscritto il medesimo valore per impostare lo stato dei led (riga 10).

Si riporta, qui di seguito, il codice della subroutine init_front, che si suppone contenuto nel file front.s: 1 /*front.s**************************************************/ 2 .include "front.inc" 3 .global init_front 4 5 init_front: 6 stmfd sp!,{r0,r1} 7 8 @ imposta GPIO_15 = nCS_1 per abilitare l’accesso alla SRAM 9 ldr r1,=0x40e0000c 10 ldr r0,[r1] 11 orr r0,r0,#0x00008000 12 str r0,[r1] 13 14 ldr r1,=0x40e00054 15 ldr r0,[r1] 16 orr r0,r0,#0x80000000 17 str r0,[r1] 18 19 @ imposta il memory timing relativo a nCS_4 e nCS_5 20 ldr r0,=0x26e026e0 21 ldr r1,=0x48000010 22 str r0,[r1] 23 24 @ imposta GPIO_33 = nCS_5 per abilitare l’accesso al front panel 25 @ direzione output 26 ldr r1,=0x40e00010 27 ldr r0,[r1] 28 orr r0,r0,#0x00000002 29 str r0,[r1] 30 31 @ alternate function 2 32 ldr r1,=0x40e0005c 33 ldr r0,[r1] 34 orr r0,r0,#0x00000008 35 str r0,[r1] 37 ldmfd sp!,{r0,r1} 38 mov pc,lr 39 .end

Page 79: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

79

5.10.2 Compilazione

In questo esempio il modulo eseguibile viene costruito a partire da due moduli sorgente, contenuti in file separati: questi due file vanno quindi assemblati separatamente per produrre i corrispondenti moduli oggetto; questi ultimi devono poi essere collegati dal linker.

Ecco i comandi con cui si ottiene quanto indicato : xscale-elf-as -gstabs -o led1.o led1.s

xscale-elf-as -gstabs -o front.o front.s

xscale-elf-ld -Ttext 0x00100000 -o led1 led1.o front.o

Nel corso dell’assemblaggio di led1.s l'assemblatore non trova la definizione del simbolo init_front, che viene pertanto lasciato irrisolto: al linker è demandato il compito di risolvere, nella costruzione del modulo eseguibile, tutti i riferimenti esterni di ciascun modulo oggetto, cercandone la definizione negli altri moduli.

5.10.3 Debugging

Solo una nota: dato che il programma è costituito essenzialmente da un ciclo che viene eseguito indefinitamente (righe 9-11) si suggerisce di collocare un breakpoint in almeno una delle istruzioni del ciclo stesso.

Page 80: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

80

5.11 Il pannello frontale: i pulsanti

Sul pannello frontale sono presenti due pulsanti, collegati a due dei pin GPIO (general purpose I/O) del PXA255.

Le possibilità di utilizzazione dei pulsanti sono molte (ad es. possono essere generare interruzioni sul livello, oppure su un fronte); in questo esempio ci si limita a leggerne lo stato e a rilevare se sono premuti o meno: il programma fa scorrere verso destra o verso sinistra l’illuminazione di un led, in seguito alla pressione del pulsante corrispondente. 1 /*led2.s***************************************************/ 2 .include "front.inc" 3 .global _start 4 5 _start: 6 ldr sp, =stack @ inizializza lo stack pointer 7 bl init_front @ chiama la subr. init_front 8 ldr r1, =LED_ADDR @ indirizzo di led e switch 9 movs r0, #1 10 strh r0, [r1] @ illumina il led di sinistra 11 ldr r3, =BUT_ADDR @ indirizzo dei pin GPIO 12 loop: bl delay @ lascia passare un po’ di tempo 13 ldr r2, [r3] @ legge lo stato dei pulsanti 14 tst r2, #LEF_MASK @ è premuto quello di sinistra? 15 moveq r0, r0, ror #31 @ si: ruota verso sinistra 16 tst r2, #RIG_MASK @ è premuto quello di destra? 17 moveq r0, r0, ror #1 @ si: ruota verso destra 18 19 @ azzera i bit che escono dall’area visibile (word meno signif.) 20 bics r0, r0, #0x00010000 @ bit uscito a sinistra 21 bicnes r0, r0, #0x80000000 @ bit uscito a destra 22 strh r0, [r1] @ riscrive sui led 23 bne loop @ continua se non nullo 24 _end: b _end @ trappola 25 26 .func delay 27 delay: @ introduce un ritardo (~ 0.1 s) 28 stmfd sp!, {r0} 29 @ 20.185.088 * 2 / 400MHz ~= 0.1 sec 30 mov r0, #0x01340000 @ 0x01340000 = 20.185.088 31 d_loop: subs r0, r0, #1 32 bne d_loop 33 ldmfd sp!, {r0} 34 mov pc, lr 35 .endfunc 36 37 .bss 38 .space 4096 39 stack: .space 4 40 41 .end

Page 81: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

81

5.11.1 Il codice

L'inizializzazione (righe 6-8) è identica a quella dell'esercizio precedente; si parte poi con il led più a sinistra illuminato.

Il corpo del programma è costituito dal loop compreso tra le righe 12 e 23: viene caricato in r2 il word contenente lo stato dei pulsanti; con le istruzioni tst (righe 14 e 16), che effettuano un AND bit a bit, si esamina lo stato dei bit corrispondenti ai pulsanti di interesse (sinistro e destro): se viene rilevato un bit nullo, si opera la rotazione di una posizione verso sinistra o, rispettivamente, verso destra (si ricordi che il bit corrispondente ad un pulsante viene azzerato quando questo è premuto); con le due istruzioni bic (righe 20 e 21) si azzera l'eventuale bit 1 che fosse fuoriuscito dai 16 bit visibili sui led, in seguito ad una rotazione verso sinistra del bit più significativo, oppure verso destra del bit meno significativo; viene inoltre abilitato l'aggiornamento dei bit di stato in modo da rilevare se il risultato è nullo: in tal caso, dopo aver scritto il valore sui led (riga 22), si termina il loop.

Il loop comprende, come prima istruzione (riga 12), una chiamata alla subroutine delay, il cui unico scopo è di far trascorrere un po’ di tempo (circa 0.1 s.), al fine di rendere percepibile lo scorrimento della illuminazione dei led: in assenza di questo ritardo lo scorrimento sarebbe talmente veloce da essere non percepibile.

5.11.2 Compilazione

Come nel caso precedente, è necessario assemblare separatamente i due moduli sorgente e collegare tramite il linker i corrispondenti moduli oggetto. I comandi sono: xscale-elf-as -gstabs -o led2.o led2.s

xscale-elf-as -gstabs -o front.o front.s

xscale-elf-ld -Ttext 0x00100000 -o led2 led2.o front.o

5.11.3 Debugging

In questo programma le istruzioni che vengono eseguite dipendono da un evento esterno (la pressione di uno o dell’altro pulsante).

Se si volessero eseguire ad una ad una le istruzioni del loop (righe 12-23), sarebbe consigliabile utilizzare la modalità next, anziché step (per evitare di eseguire ad una ad una anche le numerosissime istruzioni della subroutine delay).

Si suggerisce di impostare un breakpoint alla riga 13, ove viene rilevato l'evento: se l’evento provoca una modifica di r2, si può procedere con modalità step per verificare l’effetto della modifica, altrimenti conviene lasciar proseguire l’esecuzione del programma.

Page 82: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

82

Può essere interessante provare ad eliminare la chiamata alla subroutine delay (com-mentando parte della riga 12), oppure provare a modificare il numero delle iterazioni da essa eseguite (impostando un valore immediato diverso alla riga 30) e constatare l’effetto di queste modifiche.

Page 83: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

83

5.12 Il display LCD

Si passa ora a fornire alcuni esempi intesi a descrivere le possibilità di utilizzare il display LCD collegato alla scheda. Per abilitare l'uso del display, è necessario eseguire preventivamente una serie di operazioni di inizializzazione: allo scopo nel file sorgente lcd.s (vedi paragrafo 5.13) sono presenti alcune subroutine con le quali è possibile inizializzare in diversi modi il controller LCD del PXA255.

Il principio di funzionamento del controller LCD è abbastanza semplice: l’insieme dei pixel che costituiscono l’immagine da visualizzare sul display va “scritto”, con le modalità previste, in un’apposita area di memoria (qui chiamata framebuffer); il controller LCD interpreta il contenuto di quell’area di memoria e lo trasferisce sul display a formare la corrispondente immagine.

Nel file lcd.s (vedi paragrafo 5.13) sono presenti tre subroutine di inizializzazione (lcd_init_4bpp, lcd_init_8bpp, lcd_init_16bpp) che inizializzano il display controller in modo che esso operi prevedendo che ciascun pixel sia rappresentato, nel framebuffer, con 4, 8 o 16 bit, rispettivamente.

Nella modalità con 4 bit per pixel (bpp) ciascun punto dell’immagine può assumere uno di 24 = 16 colori diversi; i 16 colori sono definiti da una palette (tavolozza) costituita da una tabella di 16 elementi da 16 bit; i 16 bit di ciascun elemento definiscono il corrispondente colore secondo la codifica RGB 565 (in cui i 5 bit più significativi indicano la componente rossa, i 6 bit centrali la componente verde e i 5 bit meno significativi la componente blu del colore stesso); i 4 bit di ciascun pixel vengono interpretati dal controller LCD come l’indice dell’elemento nella palette che ne definisce il colore.

Nella modalità con 8 bpp ciascun pixel può assumere uno di 28 = 256 colori diversi; la palette contiene 256 elementi da 16 bit (con codifica RGB 565).

Nella modalità con 16 bpp non è presente una palette, in quanto ciascun pixel è direttamente rappresentato nel framebuffer tramite le sue componenti RGB 565.

Le caratteristiche delle tre diverse modalità sono riassunte nella seguente tabella: subroutine colori bpp palette lcd_init_4bpp 16 4 SI lcd_init_8bpp 256 8 SI lcd_init_16bpp 65536 16 NO

Tutte tre le subroutine di inizializzazione richiedono, come parametri di ingresso, nei registri r8 e r9 gli indirizzi rispettivamente del framebuffer e della palette. Se in r8 e r9 vengono passati valori nulli, le subroutine usano i valori di default: 0x01000000 per il framebuffer, e le palette a 8 e 16 colori predefinite nel segmento .data nel file lcd.s; come parametri di uscita le subroutine ritornano, in r8 e r9, gli indirizzi del framebuffer e della palette.

Page 84: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

84

5.12.1 Disegnare a 16 Colori

Il primo esempio prevede di inizializzare il display a 16 colori e di visualizzare sullo schermo 16 rettangoli colorati ciascuno con uno diverso dei 16 colori della palette. 1 /*color1.s*************************************************/ 2 .global _start 3 .text 4 _start: 5 ldr sp, =stack @ inizializza lo stack pointer 6 7 bic r8,r8,r8 @ r8=0 (framebuffer predefinito) 8 bic r9,r9,r9 @ r9=0 (palette predefinita) 9 bl lcd_init_4bpp @ in r8: ind. del FB; in R9 ind. PAL 10 11 mov r3, #320/4 @ 1/4 della larghezza dello schermo 12 mov r4, #240/4 @ 1/4 della altezza dello schermo 13 mov r0, #0 @ indice del colore nella palette 14 m_loop: 15 bic r5, r0, #0x0C @ 2 LSb dell’indice colore: 0,1,2,3 16 mul r1, r5, r3 @ ascissa vertice del rettangolo 17 mov r5, r0, lsr #2 @ 2 MSb dell’indice colore: 0,1,2,3 18 mul r2, r5, r4 @ ordinata vertice del rettangolo 19 bl draw_box_4bpp @ disegna il rettangolo 20 add r0, r0, #1 @ incrementa l’indice del colore 21 cmp r0, #16 @ era l’ultimo colore? 22 blt m_loop @ no: disegna un altro rettangolo 23 24 _end: b _end @ trappola 25 26 .func draw_box_4bpp 27 /*************************************************************/ 28 /* r0 : colore */ 29 /* r1 : ascissa x (in pixel) del vertice superiore sinistro */ 30 /* r2 : ordinata y (in pixel) del vertice superiore sinistro */ 31 /* r3 : larghezza (in pixel) del rettangolo */ 32 /* r4 : altezza (in pixel) del rettangolo */ 33 /* r8 : indirizzo del framebuffer (FB) */ 34 /*************************************************************/ 35 draw_box_4bpp: 36 stmfd sp!,{r0,r3-r8} 37 mov r7, #320 @ n. pixel in 1 riga dello schermo 38 mul r5, r2, r7 @ n. pixel in y righe (da saltare) 39 add r5, r5, r1 @ + x pixel della riga y 40 mov r5, r5, lsr #1 @ 1 pixel occupa solo 1/2 byte 41 add r8, r8, r5 @ r8 = indirizzo di memoria del 42 @ vertice superiore sinistro del 43 @ rettangolo (nel framebuffer) 44 add r0, r0, r0, lsl #4 @ 2 pixel uguali nel LSB di r0 45 sub r3, r3, #1 @ contatore di colonne (pixel/riga 46 sub r4, r4, #1 @ contatore di righe del box 47 mov r6, r3 @ salva il contatore di colonne 48 db_loop: @ scrive nel FB: parte dal vertice inf dx 49 mul r5, r7, r4 @ indice (pxl) di riga (parte dall’ultima) 50 add r5, r5, r3 @ indice (pxl) di colonna (dall’ultima) 51 strb r0, [r8, r5, lsr #1]@ scrive nel FB 2 pxl alla volta

Page 85: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

85

52 subs r3, r3, #1 @ decrementa l’indice di colonna 53 bpl db_loop @ scrivi altri pxl della riga 54 mov r3, r6 @ fine riga: ripristina il cont. di col. 55 subs r4, r4, #1 @ decrementa l’indice di riga 56 bpl db_loop @ scrivi un’altra riga 57 58 ldmfd sp!,{r0,r3-r8} 59 mov pc,lr 60 .endfunc 61 62 .bss 63 .space 4096 @ spazio per lo stack 64 stack: .space 4 @ base dello stack 65 .end

5.12.1.1 Il codice

Il codice è relativamente semplice: nel corpo principale del programma, dopo aver chiamato la subroutine di inizializzazione (modalità 4 bpp) e avendo ottenuto da essa in r8 ed r9 gli indirizzi (predefiniti) del framebuffer (FB) e della palette (PAL), conoscendo le dimensioni dello schermo (320 × 240 pixel) e volendo disegnare 16 rettangoli uguali e contigui posizionati come una matrice 4 per 4, vengono preparate le coordinate del vertice superiore sinistro di ciascuno dei rettangoli e ne viene comandata la visualizzazione chiamando la subroutine draw_box_4bpp.

All'interno della subroutine draw_box_4bpp viene, per prima cosa (righe 37-41), calcolato l'effettivo indirizzo di memoria dell'angolo superiore sinistro del rettangolo da disegnare; successivamente, nel doppio loop principale (righe 48-56), viene disegnato il rettangolo per righe successive, partendo dall'angolo inferiore destro.

5.12.1.2 Compilazione

I comandi sono i soliti: xscale-elf-as -gstabs -o color1.o color1.s

xscale-elf-as -gstabs -o lcd.o lcd.s

xscale-elf-ld -Ttext 0x00100000 -o color1 color1.o lcd.o

5.12.1.3 Debugging

Impostando un breakpoint in corrispondenza dell’istruzione di chiamata alla subroutine draw_box_4bpp (riga 19) è possibile seguire la visualizzazione dei singoli rettangoli e verificare, nei registri r0-r4 ed r8, i valori dei parametri passati alla subroutine.

Per verificare la modalità di colorazione di ciascun rettangolo si può definire un breakpoint nel loop esterno della subroutine draw_box_4bpp (ad es. alla riga 56), oppure nel loop interno (ad es. alla riga 53) se si volesse controllare, molto più

Page 86: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

86

lentamente, la colorazione di una coppia di pixel alla volta.

Può essere interessante verificare l’uso della palette: dopo che il programma è stato completamente eseguito ed è “intrappolato” nella riga 24, si apra una finestra di visualizzazione della memoria all'indirizzo della palette (indirizzo contenuto in r9): i primi 16 half-word (da 16 bit) visualizzati sono i 16 elementi della palette correntemente attiva; si può provare a modificare questi valori e constatare le variazioni di colore dei rettangoli sullo schermo.

Si osservi che ciò avviene anche se il processore non esegue alcuna istruzione (ad esempio avendolo fermato con un breakpoint alla riga 24). Si ha così conferma del fatto che il trasferimento sullo schermo del contenuto del framebuffer utilizzando i colori specificati dalla palette, è un'operazione che viene compiuta autonomamente dal controller LCD, via DMA, senza l’intervento del processore.

Page 87: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

87

5.12.2 Disegnare a 256 Colori

Il secondo esempio, simile al primo, prevede di inizializzare il display a 256 colori e di visualizzare sullo schermo 256 rettangoli, disposti a matrice 16 per 16, con i 256 colori della palette.

Il programma è simile al precedente salvo le modifiche legate al fatto che ora un singolo pixel è contenuto in un intero byte. 1 /*color2.s*************************************************/ 2 .global _start 3 .text 4 _start: 5 ldr sp, =stack @ inizializza lo stack pointer 6 7 bic r8,r8,r8 @ r8=0 (framebuffer predefinito) 8 bic r9,r9,r9 @ r9=0 (palette predefinita) 9 bl lcd_init_8bpp @ in r8: ind. del FB; in R9 ind. PAL 10 11 mov r3, #320/16 @ 1/4 della larghezza dello schermo 12 mov r4, #240/16 @ 1/4 della altezza dello schermo 13 mov r0, #0 @ indice del colore nella palette 14 m_loop: 15 bic r5, r0, #0xf0 @ 4 LSb dell’indice colore: 0..15 16 mul r1, r5, r3 @ ascissa vertice del rettangolo 17 mov r5, r0, lsr #4 @ 4 MSb dell’indice colore: 0..15 18 mul r2, r5, r4 @ ordinata vertice del rettangolo 19 bl draw_box_8bpp @ disegna il rettangolo 20 add r0, r0, #1 @ incrementa l’indice del colore 21 cmp r0, #256 @ era l’ultimo colore? 22 ble m_loop @ no: disegna un altro rettangolo 23 24 _end: b _end @ trappola 25 26 .func draw_box_8bpp 27 /*************************************************************/ 28 /* r0 : colore */ 29 /* r1 : ascissa x (in pixel) del vertice superiore sinistro */ 30 /* r2 : ordinata y (in pixel) del vertice superiore sinistro */ 31 /* r3 : larghezza (in pixel) del rettangolo */ 32 /* r4 : altezza (in pixel) del rettangolo */ 33 /* r8 : indirizzo del framebuffer (FB) */ 34 /*************************************************************/ 35 draw_box_8bpp: 36 stmfd sp!,{r3-r8} 37 mov r7, #320 @ n. pixel in 1 riga dello schermo 38 mul r5, r2, r7 @ n. pixel in y righe (da saltare) 39 add r5, r5, r1 @ + x pixel della riga y 40 add r8, r8, r5 @ r8 = indirizzo di memoria del 41 @ vertice superiore sinistro del 42 @ rettangolo (nel framebuffer) 43 sub r3, r3, #1 @ contatore di colonne (pixel/riga) 44 sub r4, r4, #1 @ contatore di righe del box 45 mov r6, r3 @ salva il contatore di colonne

Page 88: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

88

46 db_loop: @ scrive nel FB: parte dal vertice inf dx 47 mul r5, r7, r4 @ indice (pxl) di riga (parte dall’ultima) 48 add r5, r5, r3 @ indice (pxl) di colonna (dall’ultima) 49 strb r0, [r8, r5] @ scrive nel FB 2 pxl alla volta 50 subs r3, r3, #1 @ decrementa l’indice di colonna 51 bpl db_loop @ scrivi altri pxl della riga 52 mov r3, r6 @ fine riga: ripristina il cont. di col. 53 subs r4, r4, #1 @ decrementa l’indice di riga 54 bpl db_loop @ scrivi un’altra riga 55 56 ldmfd sp!,{r3-r8} 57 mov pc,lr 58 .endfunc 59 60 .bss 61 .space 4096 @ spazio per lo stack 62 stack: .space 4 @ base dello stack 63 .end

5.12.2.1 Compilazione

I comandi sono i soliti: xscale-elf-as -gstabs -o color2.o color2.s

xscale-elf-as -gstabs -o lcd.o lcd.s

xscale-elf-ld -Ttext 0x00100000 -o color2 color2.o lcd.o

5.12.2.2 Debugging

Le operazioni di debug che si consiglia di eseguire sono le stesse dell’esempio precedente, tenendo presente il fatto che adesso la palette è una tabella di 256 halfword.

Page 89: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

89

5.12.3 Scrivere caratteri sul display

Questo terzo esempio si propone di descrivere l’uso del display a 16bpp con un obiettivo un po' più complesso rispetto ai due esempi precedenti: scrivere dei caratteri sullo schermo.

Per fare ciò è necessario avere a disposizione le immagini dei caratteri, nel formato richiesto, da poter ricopiare nelle posizioni desiderate all’interno del framebuffer.

Per questo esempio ci si è limitati a rendere disponibile l'immagine contenente i soli caratteri corrispondenti alle cifre da 0 a 9 e alle lettere maiuscole da A a F, con le quali è possibile visualizzare un numero esadecimale. L’immagine di questi caratteri (nel formato RGBA a 32bpp, che necessiterà di essere convertito al formato RGB 565 a 16bpp) si trova nel file font_tab.s, che va assemblato separatamente e collegato tramite il linker.

Il programma fa uso anche un file di tipo include (font_tab.inc), riportato qui sotto, nel quale sono definite le dimensioni (in pixel) dell'immagine e dei singoli caratteri. 1 /*font_tab.inc*********************************************/ 2 FONT_LINE = 160 @ full pixmap lenght in pixel 3 FONT_H = 15 @ altezza, in pixel, di un carattere 4 FONT_W = 10 @ larghezza, in pixel, di un carattere

Il programma completo, contenuto nel file font1.s, riempie l’intero schermo (240 × 320 pixel) di cifre esadecimali, disposte in 16 righe da 32 caratteri. 1 /*font1.s**************************************************/ 2 .global _start 3 .include "font_tab.inc" 4 .text 5 6 _start: 7 ldr sp, =stack @ inizializza lo stack pointer 8 mov r8, #0 @ r8=0 (framebuffer predefinito) 9 bl lcd_init_16bpp @ in r8: indirizzo del FB 10 mov r0, #0 @ cifra esadec. (nei 4 LSb di r0) 11 mov r2, #0 @ posiz. verticale (indice di riga) 12 l1: mov r1, #0 @ posiz. orizzont. (indice di col.) 13 l2: add r0, r1, r2 @ incrementa la cifra esadecimale 14 bic r0, r0, #0x0ff0 @ isola i 4 bit (nibble) meno sign. 15 bl putnibble @ scrive il carattere sullo schermo 16 add r1, r1, #1 @ incrementa la posizione orizzont. 17 cmp r1, #320/FONT_W-1 @ oltre l’ultima pos. nella riga? 18 ble l2 @ no: prosegue con car. successivo 19 add r2, r2, #1 @ si: incrementa la posizione vert. 20 cmp r2, #240/FONT_H-1 @ oltre l’ultima pos. nella col.? 21 ble l1 @ no: prosegue con riga successiva 22 23 24 _end: b _end @ trappola

Page 90: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

90

25 26 27 .func putnibble 28 /******************************************************************/ 29 /* calcola la pos. nel FB (240 righe × 320 colonne) ove scrivere */ 30 /* input : R0 – valore (esadecimale) da scrivere */ 31 /* R1 – posizione orizzontale [0..319] (indice di col.) */ 32 /* R2 - posizione verticale [0..239] (indice di riga) */ 33 /* R8 – indirizzo del framebuffer */ 34 /******************************************************************/ 35 putnibble: 36 stmfd sp!,{r1-r4,lr} 37 cmp r1, #320/FONT_W-1 @ verifica se ci sta nella riga 38 bhi pnb_end @ fuori schermo (lateralmente) 39 cmp r2, #240/FONT_H-1 @ verifica se ci sta nella col. 40 bhi pnb_end @ fuori schermo (verticalmente) 41 cmp r0, #FONT_LINE/FONT_W-1 42 bhi pnb_end @ valore fuori range 43 44 mov r3, r1 @ posiz. oriz. (in larghezze car.) 45 ldr r4, =FONT_W @ larg. dei caratteri (in pixel) 46 mul r1, r3, r4 @ r1 = offset orizz. (in pixel) 47 @ del carattere da scrivere 48 ldr r4, =FONT_H*320 @ n. di pixel in una riga di car. 49 mul r3, r2, r4 @ r3 = offset verticale (in pixel) 50 @ dell’inizio riga in cui scrivere 51 add r1, r1, r3 @ pos. (pixel) del car. da scriver 52 add r1, r8, r1, lsl #1 @ indir. di mem. in cui scrivere 53 @ il carattere (2 byte/pixel) 54 bl drawnibble 55 pnb_end: ldmfd sp!,{r1-r4,pc} 56 .endfunc 57 58 59 .func drawnibble 60 /**************************************************************/ 61 /* disegna un carattere sullo schermo */ 62 /* input : R0 - valore (esadecimale) da scrivere */ 63 /* R1 – indirizzo di mem. in cui scrivere il carattere*/ 64 /**************************************************************/ 65 drawnibble: 66 stmfd sp!,{r0,r2-r6,lr} 67 ldr r3, =FONT_W*4 @ larg. car. (in byte: RGBA a 32 bit) 68 mul r2, r0, r3 @ offset orizz.(byte) del car. in TAB 69 ldr r3, =font_tab @ inizio della tabella (TAB) 70 add r2, r2, r3 @ indir. I riga del car. (in TAB) 71 ldr r3, =FONT_H-1 @ indice ultima riga car (di pixel) 72 ch_1: ldr r4, =FONT_W-1 @ indice ultima colonna (di pixel) 73 ch_2: ldr r6, =FONT_LINE @ n. pixel di una riga dei 16 car 74 mul r5, r3, r6 @ offset vert.(pixel) dell’ultima riga 75 @ r5=offset vert. (pxl in TAB) dell’inizio ultima riga dei 16 car. 76 mov r6, r3, lsl #8 @ r6 = (r3*256... 77 add r6, r6, r3, lsl #6 @ ...+r3*64) = r3 * 320 78 @ r6=offset vert. (pxl su schermo) inizio ultima riga dei 16 car. 79 add r6, r6, r4 @ r6=offset su sch. r4-esimo pxl del car. 80 add r5, r5, r4 @ r5=offset in TAB r4-esimo pxl del car. 81 @ inizia dal vertice inferiore destro (VID) del carattere

Page 91: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

91

82 ldr r0, [r2, r5, lsl #2] @ carica pixel del car. da TAB 83 bl rgba2h @ lo converte da RGBA a 16 bit 84 mov r6, r6, lsl #1 @ offset su schermo (2byte/pxl) 85 strh r0, [r1, r6] @ lo scrive nel FB 86 subs r4, r4, #1 @ decrementa indice di colonna 87 bge ch_2 @ cicla se non era l’ultima 88 subs r3, r3, #1 @ decrementa indice di riga 89 bge ch_1 @ cicla se non era l’ultima 90 ldmfd sp!,{r0,r2-r6,pc} 91 .endfunc 92 93 94 .func rgba2h 95 /**********************************************************/ 96 /* convert a pixel from RGBA 32bpp format to a RGB 16bpp */ 97 /* input/output : R0 - pixel value */ 98 /**********************************************************/ 99 rgba2h: 100 stmfd sp!,{r1,r2} 101 bic r0, r0, #0xff000000 @ drop alpha 102 mov r2, r0, lsr #8 103 bic r2, r2, #0x00ff 104 bic r2, r2, #0x0700 105 bic r0, r0, #0xff0000 106 mov r1, r0, lsr #5 107 bic r1, r1, #0x001f 108 orr r2, r2, r1 109 bic r0, r0, #0x00ff00 110 mov r1, r0, lsr #3 111 orr r0, r2, r1 112 ldmfd sp!,{r1,r2} 113 mov pc, lr 114 .endfunc 115 116 .bss 117 .space 4096 118 stack: .space 4 119 .end

5.12.3.1 Il codice

Il programma è costituito, oltre che dal corpo principale, da tre subroutine: putnibble, drawnibble e rgba2h.

Per comprendere il codice è necessario tenere presente l’organizzazione del file font_tab.s: in questo file i pixel che definiscono le 16 cifre esadecimali si riferiscono ad un’unica immagine dei 16 caratteri (0123456789ABCDEF), la cui altezza FONT_H è di 15 pixel (coincidente con l’altezza di ciascun singolo carattere) e la cui larghezza complessiva è di 16*FONT_W = 160 pixel (essendo FONT_W = 10 pixel la larghezza di ciascun singolo carattere). Questa immagine può essere pensata come una tabella (TAB) di pixel, con 15 righe e 160 colonne, in cui ciascun pixel è rappresentato con 4 byte (nel formato RGBA a 32bpp). Un pixel all’interno della tabella può essere

Page 92: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

92

individuato dall’indice di riga IR (0..14) e dall’indice di colonna IC (0..159) (la riga di indice 0 è quella superiore; la colonna di indice 0 è quella più a sinistra.

Per ricopiare nel framebuffer il carattere corrispondente alla cifra i-esima (i=0..15), bisogna estrarre da TAB le 15 sequenze di 10 pixel (corrispondenti alle 15 righe dell’immagine del carattere) situate a partire dai pixel di indice IR=i*10, i*10+160, i*10+160*2, ..., i*10+160*14. In sostanza gli indici iniziali delle 15 sequenze che costituiscono la cifra i si ottengono come somma di due componenti: una componente (i*10) è fissa e costituisce l’offset “orizzontale” (in pixel) della (prima riga di pixel della) cifra i in TAB; l’altra componente è variabile (160*K, con k=0..14) e costituisce l’offset “verticale” della riga k-esima di pixel in TAB (intendendo per offset verticale la somma dei pixel di tutte le k righe precedenti).

Nel framebuffer (e nel display) i pixel sono rappresentati da 2 byte (16 bpp) codificati nel formato RGB 565: nel ricopiare i pixel dalla tabella TAB al framebuffer è quindi necessario operare la conversione da formato RGBA a formato RGB.

Per individuare la posizione dei pixel di ciascuna cifra nel framebuffer (e nel display) è utile tenere presente che il display può essere pensato sia come una tabella di pixel (da 240 righe e 320 colonne), sia come una tabella di caratteri (da 240/15 = 16 righe di caratteri e 320/10 = 32 colonne di caratteri, essendo FONT_H = 15 e FONT_W = 10).

Dopo aver inizializzato il controller LCD a 16 bpp e aver ottenuto in r8 l’indirizzo del framebuffer (righe 8 e 9), il programma inserisce: in r0 il valore della cifra esadecimale (0..15) da visualizzare (riga 10), in r1 ed r2 l’indice di riga (0..15) e, rispettivamente, l’indice di colonna (0..31) della posizione in cui il carattere va collocato sullo schermo (inteso come tabella di 16 × 32 caratteri) (righe 11 e 12). Nel loop interno (righe 13-18) viene effettuata la visualizzazione (tramite chiamata alla subroutine putnibble) di una riga di 32 caratteri sullo schemo, incrementando l’indice di colonna ad ogni iterazione; nel loop più esterno (righe 12-21) viene incrementato l’indice di riga in modo da visualizzare le 16 righe; si può osservare che il valore della cifra esadecimale da visualizzare è ottenuto (righe 13 e 14) come somma dei suoi indici di riga e di colonna: ciò fa sì che, nelle diverse righe, le stesse cifre non siano incolonnate, ma sfalsate orizzontalmente.

La subroutine putnibble, viene chiamata per visualizzare sullo schermo la cifra esadecimale il cui valore è contenuto nel nibble (4 bit) meno significativo del registro r0; la posizione in cui trasferire, nel framebuffer, i pixel della cifra (o in cui visualizzare il carattere nel display) è passata alla subroutine nei registri r1 e r2, che contengono gli indici di colonna (di caratteri) (0..31) e, rispettivamente, di riga (di caratteri) (0.. 15) della posizione della cifra stessa: in questo modo è semplice scrivere le cifre in modo allineato sul display.

Compito specifico della subroutine putnibble è di calcolare l'indirizzo di memoria (nel framebuffer) in cui copiare l'immagine corrispondente alla cifra: tenendo conto del fatto che ogni pixel occupa 2 byte nel framebuffer, questo indirizzo è ottenuto

Page 93: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

93

(riga 52) sommando all’indirizzo iniziale del framebuffer (r8) un offset pari a 2 volte la distanza (in pixel) tra il vertice superiore sinistro del rettangolo (VSSR) che conterrà il carattere e il vertice superiore sinistro del display; questa distanza è calcolata (riga 51) come somma di due componenti: una componente corrisponde alla posizione “verticale” della riga di pixel che contiene il VSSR ed è pari al numero di righe di pixel dal bordo superiore del display (dato dal prodotto dell’indice di riga r2 per l’altezza FONT_H, in pixel, di un carattere) moltiplicato per il numero (320) di pixel di una riga (righe 48 e 49); l’altra componente fornisce la posizione “orizzontale” del VSSR, cioè la sua distanza dal bordo sinistro del display ed è pari all’indice di colonna r1 moltiplicato per la larghezza FONT_W, in pixel, di ciascun carattere (righe 44-46).

La seconda subroutine, drawnibble, ha il compito di scrivere sul framebuffer (e quindi sul display) la porzione dell'immagine contenuta in TAB corrispondente al carattere i-esimo scelto (costituita dalle 15 sequenze di 10 pixel che iniziano dai pixel di indice IR= i*10+160*k, con k=0..14); nel framebuffer queste 15 sequenze di 10 pixel vanno scritte, previa conversione da RGBA a RGB (ottenuta chiamando la subroutine rgba2h) a partire dalle posizioni corrispondenti ai pixel di indice i*10+320*k, per la prima serie di 16 caratteri visualizzati; 160+i*10+320*k, per la seconda serie di 16 caratteri (che vengono visualizzati di seguito, nella stessa riga); 320*15+i*10+320*k, per la terza serie; 160+320*15+i*10+320*k per la quarta, e così via.

Il trasferimento dei pixel di ciascun carattere da TAB al framebuffer viene effettuato a partire dal vertice inferiore destro.

Con le istruzioni alle righe 67 e 68 viene inserito in r2 l’offset (in byte) all’interno di TAB (dell’inizio della prima riga di pixel) del carattere i-esimo (essendo l’indice i contenuto in r0); questo offset, aggiunto all’indirizzo iniziale di TAB (font_tab), viene trasformato nel corrispondente indirizzo di memoria (righe 69 e 70); in r3 ed r4 vengono poi inseriti gli indici (di riga e di colonna) del pixel corrispondente al vertice inferiore destro (VID) del carattere (righe 71 e 72); nel ciclo compreso tra le righe 73 e 87, a partire dal pixel VID e decrementando ad ogni iterazione l’indice di colonna (riga 86), si trasferiscono nel framebuffer i 10 pixel di una riga del carattere: si calcolano (in r5) l’offset del pixel in TAB (righe 73, 74 e 80), e (in r6) l’offset del corrispondente pixel nel framebuffer (righe 76, 77 e 79), si prelevano i 4 byte che rappresentano il pixel (formato RGBA) in TAB (riga 82), si ottiene il pixel convertito in formato RGB (2 byte) (riga 83), si moltiplica per 2 l’offset di pixel contenuto in r6 per ottenere l’offset di byte nel framebuffer (riga 84) (questa operazione va fatta con un’istruzione apposita perché la successiva istruzione strh, a differenza della str, non prevede lo scorrimento dell’operando), si scrive lo halfword contenente la codifica RGB del pixel alla posizione calcolata nel framebuffer (riga 85); ad ogni iterazione del ciclo più esterno (righe 72..89), si rieseguono le 10 iterazioni del ciclo interno, dopo aver decrementato l’indice di riga (riga 88), per trasferire nel framebuffer i pixel di un’altra riga.

Page 94: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

94

L'ultima subroutine, rgba2h, serve per convertire un singolo pixel dal formato RGBA a 32 bit in cui l'immagine è salvata, al formato RGB 16bit in cui va disegnata.

5.12.3.2 Compilazione

I comandi sono i soliti: xscale-elf-as -gstabs -o font1.o font1.s

xscale-elf-as -gstabs -o font_tab.o font_tab.s

xscale-elf-as -gstabs -o lcd.o lcd.s

xscale-elf-ld -Ttext 0x00100000 -o font1 font1.o font_tab.o lcd.o

5.12.3.3 Note

È abbastanza semplice creare un nuovo font, usando il programma di grafica Gimp disponibile per Linux e Windows: bisogna dapprima, come si è fatto per l’esempio qui presentato, creare un'immagine contenente, in un’unica riga, tutti caratteri che si vogliono usare, rappresentati con un font di tipo non proporzionale (in cui tutti i caratteri abbiano la stessa larghezza), come ad esempio il courier; questa immagine va poi salvata nel formato C-Source, facendo attenzione ad utilizzare il formato dati RGBA (save alpha channel); successivamente il file .c ottenuto va copiato nel directory di lavoro con il nome font_tab.c; usando infine il comando: make font_tab.s

posto che sia presente il Makefile distribuito con i sorgenti, viene generato appunto il file font_tab.s che potrà poi essere utilizzato da un programma simile a font1.

Page 95: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

95

5.13 Libreria per l’uso del disply LCD

Si riporta qui sotto il listing completo di 3 file utilizzati negli esercizi sul display LCD (vedi paragrafo 5.12):

1. lcd.s: contenente, oltre alle 3 subroutine di inizializazione del controller LCD (a 4bpp, a 8bpp, a 16bpp), alcune altre subroutine, utilizzate per impostare i parametri operativi del controller LCD, e i dati relativi alla tavolozza (palette) a 16 colori (4bpp);

2. palette256.s: file di dati contenente la palette a 256 colori (8bpp);

3. font_tab.s: file di dati contenente l’immagine delle 6 cifre esadecimali (nel formato RGBD a 32bpp).

L’insieme di queste subroutine e di questi file dati può essere considerato come una “libreria” per l’uso del display, cioè una raccolta di moduli software utilizzabili per la programmazione di applicazioni che fan uso del display LCD. 1 /*lcd.s****************************************************/ 2 .global lcd_init_4bpp, lcd_init_8bpp, lcd_init_16bpp 3 4 .text 5 .func lcd_init_4bpp 6 /**********************************************************/ 7 /* lcd_init_4bpp: inizializza il display per 16 colori */ 8 /* input: R8 – indirizzo del framebuffer */ 9 /* input: R9 – indirizzo della palette */ 10 /* entrambi gli indirizzi devono essere multiplo di 16 */ 11 /* se R8 e/o R9 = 0x00, vengono usati valori predefiniti*/ 12 /* output: R8 - indirizzo del framebuffer */ 13 /* output: R9 - indirizzo della palette */ 14 /**********************************************************/ 15 lcd_init_4bpp: 16 stmfd sp!, {r0,r1,r2,lr} 17 18 cmp r8, #0x00 @ se = 0, usa val. predefinito 19 ldreq r8, =0x01000000 20 cmp r9, #0x00 @ se = 0, usa val. predefinito 21 ldreq r9, =palette_4bpp 22 23 @ accensione del display LCD 24 ldr r1,=0x64000000 25 mvn r0,#0x0000 26 bic r0,r0,#0x0080 27 strh r0,[r1] 28 29 bl lcd_disable 30 bl lcd_gpio_init 31 32 @ catena di descrittori DMA per FB + PAL 33 ldr r1, =frame_descr 34 ldr r2, =pal_descr 35 ldr r0, [r1] 36 add r0, r0, r2 37 str r0, [r1] 38 39 ldr r0, [r2] 40 add r0, r0, r1 41 str r0, [r2] 42 43 ldr r0, [r1, #4] 44 add r0, r0, r8 45 str r0, [r1, #4] 46 47 ldr r0, [r2, #4]

Page 96: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

96

48 add r0, r0, r9 49 str r0, [r2, #4] 50 51 ldr r0, [r1, #12] 52 add r0, r0, #(320*240/2) 53 str r0, [r1, #12] 54 55 ldr r0, [r2, #12] 56 add r0, r0, #(16*2) 57 str r0, [r2, #12] 58 59 mov r0, r1 60 bl lcd_dma_init 61 62 ldr r2, =lccrx_4bpp 63 bl lcd_timing_init 64 65 ldmfd sp!,{r0,r1,r2,lr} 66 mov pc,lr 67 .endfunc 68 69 .func lcd_init_8bpp 70 /**********************************************************/ 71 /* lcd_init_8bpp: inizializza il display per 256 colori */ 72 /* input: R8 – indirizzo del framebuffer */ 73 /* input: R9 – indirizzo della palette */ 74 /* entrambi gli indirizzi devono essere multiplo di 16 */ 75 /* se R8 e/o R9 = 0x00, vengono usati valori predefiniti*/ 76 /* output: R8 - indirizzo del framebuffer */ 77 /* output: R9 - indirizzo della palette */ 78 /**********************************************************/ 79 lcd_init_8bpp: 80 stmfd sp!, {r0,r1,r2,lr} 81 82 cmp r8, #0x00 @ se = 0, usa val. predefinito 83 ldreq r8, =0x01000000 84 cmp r9, #0x00 @ se = 0, usa val. predefinito 85 ldreq r9, =palette_8bpp 86 87 @ accensione del display LCD 88 ldr r1,=0x64000000 89 mvn r0,#0x0000 90 bic r0,r0,#0x0080 91 strh r0,[r1] 92 93 bl lcd_disable 94 bl lcd_gpio_init 95 96 @ catena di descrittori DMA per FB + PAL 97 ldr r1, =frame_descr 98 ldr r2, =pal_descr 99 ldr r0, [r1] 100 add r0, r0, r2 101 str r0, [r1] 102 103 ldr r0, [r2] 104 add r0, r0, r1 105 str r0, [r2] 106 107 ldr r0, [r1, #4] 108 add r0, r0, r8 109 str r0, [r1, #4] 110 111 ldr r0, [r2, #4] 112 add r0, r0, r9 113 str r0, [r2, #4] 114 115 ldr r0, [r1, #12] 116 add r0, r0, #(320*240) 117 str r0, [r1, #12] 118 119 ldr r0, [r2, #12] 120 add r0, r0, #(256*2) 121 str r0, [r2, #12] 122 123 mov r0, r1 124 bl lcd_dma_init 125

Page 97: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

97

126 ldr r2, =lccrx_8bpp 127 bl lcd_timing_init 128 129 ldmfd sp!,{r0,r1,r2,lr} 130 mov pc,lr 131 .endfunc 132 133 .func lcd_init_16bpp 134 /**********************************************************/ 135 /* lcd_init_16bpp: inizializza il display per 65536 colori*/ 136 /* input: R8 – indirizzo del framebuffer */ 137 /* l’indirizzo devo essere multiplo di 16 */ 138 /* se R8 = 0x00, viene usato il valore predefinito */ 139 /* output: R8 - indirizzo del framebuffer */ 140 /**********************************************************/ 141 lcd_init_16bpp: 142 stmfd sp!, {r0,r1,r2,lr} 143 144 cmp r8, #0x00 @ se = 0, usa val. predefinito 145 ldreq r8, =0x01000000 146 147 @ accensione del display LCD 148 ldr r1,=0x64000000 149 mvn r0,#0x0000 150 bic r0,r0,#0x0080 151 strh r0,[r1] 152 153 bl lcd_disable 154 bl lcd_gpio_init 155 156 @ descrittore DMA per FB 157 ldr r1, =frame_descr 158 ldr r0, [r1] 159 add r0, r0, r1 160 str r0, [r1] 161 162 ldr r0, [r1, #4] 163 add r0, r0, r8 164 str r0, [r1, #4] 165 166 ldr r0, [r1, #12] 167 add r0, r0, #(320*240*2) 168 str r0, [r1, #12] 169 170 mov r0, r1 171 bl lcd_dma_init 172 173 ldr r2, =lccrx_16bpp 174 bl lcd_timing_init 175 176 ldmfd sp!,{r0,r1,r2,lr} 177 mov pc,lr 178 .endfunc 179 180 .func lcd_disable 181 /**********************************************************/ 182 /* lcd_disable: disattiva il controller LCD */ 183 /**********************************************************/ 184 LCCR0 = 0x44000000 185 LCSR = 0x44000038 186 lcd_disable: 187 ldr r1, =LCCR0 188 ldr r0, [r1] 189 tst r0, #0x0001 @ se non è già disattivo 190 beq disabled 191 192 orr r0, r0, #0x0400 @ imposta il campo DIS 193 str r0, [r1] 194 195 ldr r1, =LCSR 196 w_done: ldr r0, [r1] 197 tst r0, #0x0001 @ attende completamento 198 beq w_done @ della disattivazione 199 200 mvn r0, #0 @ reset dello stato 201 str r0, [r1] 202 203 disabled:

Page 98: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

98

204 mov pc, lr 205 .endfunc 206 207 208 .func lcd_gpio_init 209 /**********************************************************/ 210 /* Setup GPIO 58:65,74:76 to act as LCD interface */ 211 /* direction output */ 212 /* alternate function 2 */ 213 /**********************************************************/ 214 GPDR1 = 0x40E00010 215 GPDR2 = 0x40E00014 216 GAFR1U = 0x40E00060 217 GAFR2L = 0x40E00064 218 lcd_gpio_init: 219 ldr r1,=GPDR1 220 ldr r0,[r1] 221 orr r0,r0,#0xFC000000 222 str r0,[r1] 223 224 ldr r1,=GPDR2 225 ldr r0,[r1] 226 orr r0,r0,#0x00000003 227 orr r0,r0,#0x00001C00 228 str r0,[r1] 229 230 ldr r1,=GAFR1U 231 ldr r0,[r1] 232 orr r0,r0,#0x0AA00000 233 orr r0,r0,#0xA0000000 234 str r0,[r1] 235 236 ldr r1,=GAFR2L 237 ldr r0,[r1] 238 orr r0,r0,#0x0000000A 239 orr r0,r0,#0x02A00000 240 str r0,[r1] 241 242 mov pc,lr 243 .endfunc 244 245 246 .func lcd_timing_init 247 /**********************************************************/ 248 /* Setup the LCD Controller Register to generate */ 249 /* consistent timings for LCD dispay. */ 250 /* input: */ 251 /* R2: address of values to be stored in LCCR[0:3] */ 252 /**********************************************************/ 253 LCCR0 = 0x44000000 254 LCCR1 = 0x44000004 255 LCCR2 = 0x44000008 256 LCCR3 = 0x4400000C 257 lcd_timing_init: 258 ldr r1, =LCCR3 259 ldr r0, [r2, #12] 260 str r0, [r1] 261 262 ldr r1, =LCCR2 263 ldr r0, [r2, #8] 264 str r0, [r1] 265 266 ldr r1, =LCCR1 267 ldr r0, [r2, #4] 268 str r0, [r1] 269 270 ldr r1, =LCCR0 271 ldr r0, [r2] 272 str r0, [r1] 273 274 ldr r1, =LCCR0 275 orr r0, r0, #0x00000001 276 str r0, [r1] 277 278 mov pc,lr 279 .endfunc 280 281

Page 99: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

99

282 .func lcd_dma_init 283 /**********************************************************/ 284 /* lcd_dma_init : setup dma registers */ 285 /* input: r0 - start of chain dma structure */ 286 /* (must be in DRAM) */ 287 /**********************************************************/ 288 FDADR0 = 0x44000200 289 lcd_dma_init: 290 ldr r1, =FDADR0 291 @ virtual to physical address traslation 292 add r0, r0, #0xa0000000 293 str r0,[r1] 294 295 mov pc,lr 296 .endfunc 297 298 .data 299 lccrx_4bpp: 300 .long 0x0030f878 301 .long 0x0001013f 302 .long 0x000000ef 303 .long 0x0240ff09 304 305 lccrx_8bpp: 306 .long 0x0030f878 307 .long 0x0001013f 308 .long 0x000000ef 309 .long 0x0340ff09 310 311 lccrx_16bpp: 312 .long 0x0030f878 313 .long 0x0001013f 314 .long 0x000000ef 315 .long 0x0440ff09 316 317 .align 4 318 frame_descr: 319 .long 0x00000000 + 0xa0000000 320 .long 0x00000000 + 0xa0000000 321 .long 0x00000000 322 .long 0x00000000 323 324 .align 4 325 pal_descr: 326 .long 0x00000000 + 0xa0000000 327 .long 0x00000000 + 0xa0000000 328 .long 0x00000000 329 .long 0x04000000 330 331 .align 4 332 palette_4bpp: 333 .short 0x0000 @ black 334 .short 0x7800 @ dark red 335 .short 0x01e0 @ dark green 336 .short 0x79e0 @ dark yellow 337 .short 0x000f @ dark blue 338 .short 0x780f @ dark magenta 339 .short 0x03ef @ dark cyan 340 .short 0x39e7 @ dark grey 341 .short 0x7bef @ gray 342 .short 0xf800 @ red 343 .short 0x07e0 @ green 344 .short 0xffe0 @ yellow 345 .short 0x001f @ blue 346 .short 0xf81f @ magenta 347 .short 0x07ff @ cyan 348 .short 0xffff @ white 349 350 .align 4 351 palette_8bpp: 352 .include "palette256.s" 353 354 .end

Page 100: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

100

1 /* palette256.s**********************************************/ 2 .short 0x0420 @ 0 33 0 3 .short 0x0380 @ 0 28 0 4 .short 0x02c0 @ 0 22 0 5 .short 0x0200 @ 0 16 0 6 .short 0x0160 @ 0 11 0 7 .short 0x28a0 @ 5 5 0 8 .short 0x5800 @ 11 0 0 9 .short 0x8000 @ 16 0 0 10 .short 0x03e0 @ 0 31 0 11 .short 0x0320 @ 0 25 0 12 .short 0x0260 @ 0 19 0 13 .short 0x01a0 @ 0 13 0 14 .short 0x0100 @ 0 8 0 15 .short 0x2840 @ 5 2 0 16 .short 0x5800 @ 11 0 0 17 .short 0x8000 @ 16 0 0 18 .short 0x0380 @ 0 28 0 19 .short 0x02c0 @ 0 22 0 20 .short 0x0200 @ 0 16 0 21 .short 0x0160 @ 0 11 0 22 .short 0x00a0 @ 0 5 0 23 .short 0x2800 @ 5 0 0 24 .short 0x5800 @ 11 0 0 25 .short 0x8000 @ 16 0 0 26 .short 0x0320 @ 0 25 0 27 .short 0x0260 @ 0 19 0 28 .short 0x01c0 @ 0 14 0 29 .short 0x0100 @ 0 8 0 30 .short 0x0040 @ 0 2 0 31 .short 0x2800 @ 5 0 0 32 .short 0x5800 @ 11 0 0 33 .short 0x8000 @ 16 0 0 34 .short 0x02c0 @ 0 22 0 35 .short 0x0220 @ 0 17 0 36 .short 0x0160 @ 0 11 0 37 .short 0x00a0 @ 0 5 0 38 .short 0x0000 @ 0 0 0 39 .short 0x2800 @ 5 0 0 40 .short 0x5800 @ 11 0 0 41 .short 0x8000 @ 16 0 0 42 .short 0x0287 @ 0 20 7 43 .short 0x01c7 @ 0 14 7 44 .short 0x0107 @ 0 8 7 45 .short 0x0047 @ 0 2 7 46 .short 0x0007 @ 0 0 7 47 .short 0x2807 @ 5 0 7 48 .short 0x5807 @ 11 0 7 49 .short 0x8007 @ 16 0 7 50 .short 0x022e @ 0 17 14 51 .short 0x016e @ 0 11 14 52 .short 0x00ae @ 0 5 14 53 .short 0x000e @ 0 0 14 54 .short 0x000e @ 0 0 14 55 .short 0x280e @ 5 0 14 56 .short 0x580e @ 11 0 14 57 .short 0x800e @ 16 0 14 58 .short 0x01d5 @ 0 14 21 59 .short 0x0115 @ 0 8 21 60 .short 0x0075 @ 0 3 21 61 .short 0x0015 @ 0 0 21 62 .short 0x0015 @ 0 0 21 63 .short 0x2815 @ 5 0 21 64 .short 0x5815 @ 11 0 21 65 .short 0x8015 @ 16 0 21 66 .short 0x0620 @ 0 49 0 67 .short 0x0580 @ 0 44 0 68 .short 0x04c0 @ 0 38 0 69 .short 0x1400 @ 2 32 0 70 .short 0x4360 @ 8 27 0 71 .short 0x6aa0 @ 13 21 0 72 .short 0x99e0 @ 19 15 0 73 .short 0xc120 @ 24 9 0 74 .short 0x05e0 @ 0 47 0 75 .short 0x0520 @ 0 41 0 76 .short 0x0460 @ 0 35 0 77 .short 0x13a0 @ 2 29 0 78 .short 0x4300 @ 8 24 0

Page 101: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

101

79 .short 0x6a40 @ 13 18 0 80 .short 0x9980 @ 19 12 0 81 .short 0xc0e0 @ 24 7 0 82 .short 0x0580 @ 0 44 0 83 .short 0x04c0 @ 0 38 0 84 .short 0x0400 @ 0 32 0 85 .short 0x1360 @ 2 27 0 86 .short 0x42a0 @ 8 21 0 87 .short 0x69e0 @ 13 15 0 88 .short 0x9940 @ 19 10 0 89 .short 0xc080 @ 24 4 0 90 .short 0x0520 @ 0 41 0 91 .short 0x0460 @ 0 35 0 92 .short 0x03c0 @ 0 30 0 93 .short 0x1300 @ 2 24 0 94 .short 0x4240 @ 8 18 0 95 .short 0x69a0 @ 13 13 0 96 .short 0x98e0 @ 19 7 0 97 .short 0xc020 @ 24 1 0 98 .short 0x04c8 @ 0 38 8 99 .short 0x0428 @ 0 33 8 100 .short 0x0368 @ 0 27 8 101 .short 0x12a8 @ 2 21 8 102 .short 0x4208 @ 8 16 8 103 .short 0x6948 @ 13 10 8 104 .short 0x9888 @ 19 4 8 105 .short 0xc008 @ 24 0 8 106 .short 0x048f @ 0 36 15 107 .short 0x03cf @ 0 30 15 108 .short 0x030f @ 0 24 15 109 .short 0x124f @ 2 18 15 110 .short 0x41af @ 8 13 15 111 .short 0x68ef @ 13 7 15 112 .short 0x982f @ 19 1 15 113 .short 0xc00f @ 24 0 15 114 .short 0x0436 @ 0 33 22 115 .short 0x0376 @ 0 27 22 116 .short 0x02b6 @ 0 21 22 117 .short 0x1216 @ 2 16 22 118 .short 0x4156 @ 8 10 22 119 .short 0x6896 @ 13 4 22 120 .short 0x9816 @ 19 0 22 121 .short 0xc016 @ 24 0 22 122 .short 0x03dd @ 0 30 29 123 .short 0x031d @ 0 24 29 124 .short 0x027d @ 0 19 29 125 .short 0x11bd @ 2 13 29 126 .short 0x40fd @ 8 7 29 127 .short 0x685d @ 13 2 29 128 .short 0x981d @ 19 0 29 129 .short 0xc01d @ 24 0 29 130 .short 0x07e0 @ 0 63 0 131 .short 0x0780 @ 0 60 0 132 .short 0x26c0 @ 4 54 0 133 .short 0x5600 @ 10 48 0 134 .short 0x8560 @ 16 43 0 135 .short 0xaca0 @ 21 37 0 136 .short 0xdbe0 @ 27 31 0 137 .short 0xfb20 @ 31 25 0 138 .short 0x07e0 @ 0 63 0 139 .short 0x0720 @ 0 57 0 140 .short 0x2660 @ 4 51 0 141 .short 0x55a0 @ 10 45 0 142 .short 0x8500 @ 16 40 0 143 .short 0xac40 @ 21 34 0 144 .short 0xdb80 @ 27 28 0 145 .short 0xfae0 @ 31 23 0 146 .short 0x0781 @ 0 60 1 147 .short 0x06c1 @ 0 54 1 148 .short 0x2601 @ 4 48 1 149 .short 0x5561 @ 10 43 1 150 .short 0x84a1 @ 16 37 1 151 .short 0xabe1 @ 21 31 1 152 .short 0xdb41 @ 27 26 1 153 .short 0xfa81 @ 31 20 1 154 .short 0x0728 @ 0 57 8 155 .short 0x0668 @ 0 51 8 156 .short 0x25c8 @ 4 46 8

Page 102: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

102

157 .short 0x5508 @ 10 40 8 158 .short 0x8448 @ 16 34 8 159 .short 0xaba8 @ 21 29 8 160 .short 0xdae8 @ 27 23 8 161 .short 0xfa28 @ 31 17 8 162 .short 0x06d0 @ 0 54 16 163 .short 0x0630 @ 0 49 16 164 .short 0x2570 @ 4 43 16 165 .short 0x54b0 @ 10 37 16 166 .short 0x8410 @ 16 32 16 167 .short 0xab50 @ 21 26 16 168 .short 0xda90 @ 27 20 16 169 .short 0xf9d0 @ 31 14 16 170 .short 0x0697 @ 0 52 23 171 .short 0x05d7 @ 0 46 23 172 .short 0x2517 @ 4 40 23 173 .short 0x5457 @ 10 34 23 174 .short 0x83b7 @ 16 29 23 175 .short 0xaaf7 @ 21 23 23 176 .short 0xda37 @ 27 17 23 177 .short 0xf997 @ 31 12 23 178 .short 0x063e @ 0 49 30 179 .short 0x057e @ 0 43 30 180 .short 0x24be @ 4 37 30 181 .short 0x541e @ 10 32 30 182 .short 0x835e @ 16 26 30 183 .short 0xaa9e @ 21 20 30 184 .short 0xd9fe @ 27 15 30 185 .short 0xf93e @ 31 9 30 186 .short 0x05df @ 0 46 31 187 .short 0x051f @ 0 40 31 188 .short 0x247f @ 4 35 31 189 .short 0x53bf @ 10 29 31 190 .short 0x82ff @ 16 23 31 191 .short 0xaa5f @ 21 18 31 192 .short 0xd99f @ 27 12 31 193 .short 0xf8df @ 31 6 31 194 .short 0x0fe0 @ 1 63 0 195 .short 0x3fe0 @ 7 63 0 196 .short 0x67e0 @ 12 63 0 197 .short 0x97e0 @ 18 63 0 198 .short 0xc760 @ 24 59 0 199 .short 0xeea0 @ 29 53 0 200 .short 0xfde0 @ 31 47 0 201 .short 0xfd20 @ 31 41 0 202 .short 0x0fe2 @ 1 63 2 203 .short 0x3fe2 @ 7 63 2 204 .short 0x67e2 @ 12 63 2 205 .short 0x97a2 @ 18 61 2 206 .short 0xc702 @ 24 56 2 207 .short 0xee42 @ 29 50 2 208 .short 0xfd82 @ 31 44 2 209 .short 0xfce2 @ 31 39 2 210 .short 0x0fe9 @ 1 63 9 211 .short 0x3fe9 @ 7 63 9 212 .short 0x67e9 @ 12 63 9 213 .short 0x9769 @ 18 59 9 214 .short 0xc6a9 @ 24 53 9 215 .short 0xede9 @ 29 47 9 216 .short 0xfd49 @ 31 42 9 217 .short 0xfc89 @ 31 36 9 218 .short 0x0ff0 @ 1 63 16 219 .short 0x3ff0 @ 7 63 16 220 .short 0x67d0 @ 12 62 16 221 .short 0x9710 @ 18 56 16 222 .short 0xc650 @ 24 50 16 223 .short 0xedb0 @ 29 45 16 224 .short 0xfcf0 @ 31 39 16 225 .short 0xfc30 @ 31 33 16 226 .short 0x0ff8 @ 1 63 24 227 .short 0x3ff8 @ 7 63 24 228 .short 0x6778 @ 12 59 24 229 .short 0x96b8 @ 18 53 24 230 .short 0xc618 @ 24 48 24 231 .short 0xed58 @ 29 42 24 232 .short 0xfc98 @ 31 36 24 233 .short 0xfbd8 @ 31 30 24 234 .short 0x0fff @ 1 63 31

Page 103: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

103

235 .short 0x3fdf @ 7 62 31 236 .short 0x671f @ 12 56 31 237 .short 0x965f @ 18 50 31 238 .short 0xc5bf @ 24 45 31 239 .short 0xecff @ 29 39 31 240 .short 0xfc3f @ 31 33 31 241 .short 0xfb9f @ 31 28 31 242 .short 0x0fff @ 1 63 31 243 .short 0x3f7f @ 7 59 31 244 .short 0x66bf @ 12 53 31 245 .short 0x961f @ 18 48 31 246 .short 0xc55f @ 24 42 31 247 .short 0xec9f @ 29 36 31 248 .short 0xfbff @ 31 31 31 249 .short 0xfb3f @ 31 25 31 250 .short 0x0fdf @ 1 62 31 251 .short 0x3f1f @ 7 56 31 252 .short 0x667f @ 12 51 31 253 .short 0x95bf @ 18 45 31 254 .short 0xc4ff @ 24 39 31 255 .short 0xec5f @ 29 34 31 256 .short 0xfb9f @ 31 28 31 257 .short 0xfadf @ 31 22 31

Page 104: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

104

/* font_tab.s**********************************************/ /* */ /* immagine delle 16 cifre esadecimali 0123456789ABCDEF */ /* nel formato RGBA (32 bpp) */ /**********************************************************/ .global font_tab font_tab: .ascii "\377\377\377\377\377\377\377\377\354\354\354\377\306\306\306\377\303\303" .ascii "\303\377\357\357\357\377\377\377\377\377\377\377\377\377\377\377\377\377" .ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" .ascii "\377\377\362\362\362\377\356\356\356\377\377\377\377\377\377\377\377\377" .ascii "\377\377\377\377\377\377\377\377\372\372\372\377\320\320\320\377\216\216" .ascii "\216\377mmm\377sss\377\252\252\252\377\365\365\365\377\377\377\377\377\377" .ascii "\377\377\377\377\377\377\377\377\377\377\377\365\365\365\377\325\325\325" .ascii "\377\274\274\274\377\306\306\306\377\361\361\361\377\377\377\377\377\377" .ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" .ascii "\377\377\377\377\377\377\377\377\377\346\346\346\377\277\277\277\377\316" .ascii "\316\316\377\371\371\371\377\377\377\377\377\377\377\377\377\377\377\377" .ascii "\377\345\345\345\377\276\276\276\377\274\274\274\377\274\274\274\377\274" .ascii "\274\274\377\274\274\274\377\331\331\331\377\377\377\377\377\377\377\377" .ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\354\354\354\377\306" .ascii "\306\306\377\277\277\277\377\323\323\323\377\362\362\362\377\377\377\377" .ascii "\377\377\377\377\377\344\344\344\377\274\274\274\377\274\274\274\377\274" .ascii "\274\274\377\274\274\274\377\274\274\274\377\274\274\274\377\274\274\274" .ascii "\377\366\366\366\377\377\377\377\377\377\377\377\377\377\377\377\377\375" .ascii "\375\375\377\321\321\321\377\275\275\275\377\323\323\323\377\367\367\367" .ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" .ascii "\377\377\377\365\365\365\377\315\315\315\377\274\274\274\377\336\336\336" .ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" .ascii "\377\377\377\377\377\377\377\373\373\373\377\322\322\322\377\274\274\274" .ascii "\377\321\321\321\377\372\372\372\377\377\377\377\377\377\377\377\377\367" .ascii "\367\367\377\314\314\314\377\274\274\274\377\274\274\274\377\274\274\274" .ascii "\377\274\274\274\377\302\302\302\377\351\351\351\377\375\375\375\377\377" .ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" .ascii "\377\370\370\370\377\316\316\316\377\274\274\274\377\304\304\304\377\351" .ascii "\351\351\377\375\375\375\377\377\377\377\377\313\313\313\377\274\274\274" .ascii "\377\274\274\274\377\274\274\274\377\304\304\304\377\347\347\347\377\377" .ascii "\377\377\377\377\377\377\377\377\377\377\377\373\373\373\377\323\323\323" .ascii "\377\274\274\274\377\274\274\274\377\274\274\274\377\274\274\274\377\274" .ascii "\274\274\377\274\274\274\377\274\274\274\377\336\336\336\377\377\377\377" .ascii "\377\322\322\322\377\274\274\274\377\274\274\274\377\274\274\274\377\274" .ascii "\274\274\377\274\274\274\377\274\274\274\377\274\274\274\377\314\314\314" .ascii "\377\377\377\377\377\375\375\375\377\304\304\304\377???\377\30\30\30\377" .ascii "\26\26\26\377888\377\275\275\275\377\377\377\377\377\377\377\377\377\377" .ascii "\377\377\377\377\377\377\377\370\370\370\377\336\336\336\377\200\200\200" .ascii "\377>>>\377\271\271\271\377\377\377\377\377\377\377\377\377\377\377\377\377" .ascii "\377\377\377\377\337\337\337\377>>>\377\15\15\15\377\34\34\34\377\15\15\15" .ascii "\377\14\14\14\377ooo\377\367\367\367\377\377\377\377\377\377\377\377\377" .ascii "\342\342\342\377;;;\377\40\40\40\377\22\22\22\377\30\30\30\377BBB\377\277" .ascii "\277\277\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377" .ascii "\377\377\377\377\377\377\377\377\377\365\365\365\377ooo\377\24\24\24\377" .ascii "QQQ\377\350\350\350\377\377\377\377\377\377\377\377\377\377\377\377\377\241" .ascii "\241\241\377\31\31\31\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22" .ascii "\377xxx\377\377\377\377\377\377\377\377\377\377\377\377\377\372\372\372\377" .ascii "\275\275\275\377222\377\30\30\30\377\24\24\24\377\37\37\37\377|||\377\377" .ascii "\377\377\377\377\377\377\377\236\236\236\377\22\22\22\377\22\22\22\377\22" .ascii "\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\340\340\340" .ascii "\377\377\377\377\377\377\377\377\377\350\350\350\377fff\377\36\36\36\377" .ascii "\23\23\23\377\37\37\37\377UUU\377\354\354\354\377\377\377\377\377\377\377" .ascii "\377\377\377\377\377\377\326\326\326\377MMM\377\34\34\34\377\22\22\22\377" .ascii "(((\377\227\227\227\377\366\366\366\377\377\377\377\377\377\377\377\377\377" .ascii "\377\377\377\377\377\377\377\351\351\351\377PPP\377\22\22\22\377TTT\377\352" .ascii "\352\352\377\377\377\377\377\377\377\377\377\344\344\344\377HHH\377\22\22" .ascii "\22\377\22\22\22\377\22\22\22\377\22\22\22\377\26\26\26\377+++\377\224\224" .ascii "\224\377\372\372\372\377\377\377\377\377\377\377\377\377\377\377\377\377" .ascii "\301\301\301\377MMM\377\34\34\34\377\22\22\22\377\26\26\26\377+++\377\217" .ascii "\217\217\377\377\377\377\377EEE\377\22\22\22\377\22\22\22\377\22\22\22\377" .ascii "\27\27\27\377000\377\211\211\211\377\357\357\357\377\377\377\377\377\360" .ascii "\360\360\377aaa\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22" .ascii "\22\22\377\22\22\22\377\22\22\22\377\213\213\213\377\377\377\377\377^^^\377"

Page 105: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

105

.ascii "\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22\377\22\22\22"

.ascii "\377\22\22\22\377III\377\377\377\377\377\342\342\342\377DDD\377\5\5\5\377"

.ascii "QQQ\377PPP\377\0\0\0\377222\377\356\356\356\377\377\377\377\377\377\377\377"

.ascii "\377\332\332\332\377hhh\377\35\35\35\377\0\0\0\377\0\0\0\377\261\261\261"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\332"

.ascii "\332\332\377111\377\222\222\222\377\326\326\326\377\235\235\235\377\35\35"

.ascii "\35\377\36\36\36\377\303\303\303\377\377\377\377\377\377\377\377\377\326"

.ascii "\326\326\377\0\0\0\377;;;\377\212\212\212\377888\377\0\0\0\377\"\"\"\377"

.ascii "\375\375\375\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\262\262\262\377\7\7\7\377\0\0\0\377CCC\377\346\346"

.ascii "\346\377\377\377\377\377\377\377\377\377\377\377\377\377\231\231\231\377"

.ascii "\22\22\22\377000\377000\377000\377000\377\211\211\211\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\300\300\300\377!!!\377\15\15\15\377hhh\377"

.ascii "yyy\377\17\17\17\377aaa\377\377\377\377\377\377\377\377\377\252\252\252\377"

.ascii "000\377000\377000\377000\377&&&\377\2\2\2\377$$$\377\346\346\346\377\377"

.ascii "\377\377\377\373\373\373\377\207\207\207\377\7\7\7\377<<<\377\212\212\212"

.ascii "\377\40\40\40\377\0\0\0\377\207\207\207\377\377\377\377\377\377\377\377\377"

.ascii "\367\367\367\377FFF\377\0\0\0\377000\377|||\377\31\31\31\377\16\16\16\377"

.ascii "\244\244\244\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\324\324\324\377\22\22\22\377\0\0\0\377\30\30\30\377\321\321\321"

.ascii "\377\377\377\377\377\377\377\377\377\362\362\362\377\212\212\212\377\2\2"

.ascii "\2\377\0\0\0\377\204\204\204\377\220\220\220\377KKK\377\0\0\0\377\22\22\22"

.ascii "\377\304\304\304\377\377\377\377\377\377\377\377\377\307\307\307\377\31\31"

.ascii "\31\377\0\0\0\377CCC\377\212\212\212\377___\377\10\10\10\377bbb\377\377\377"

.ascii "\377\377\232\232\232\377\0\0\0\377\4\4\4\377qqq\377ppp\377\14\14\14\377\0"

.ascii "\0\0\377yyy\377\370\370\370\377\370\370\370\377\265\265\265\377;;;\377\0"

.ascii "\0\0\377,,,\377\220\220\220\377\220\220\220\377\200\200\200\377\"\"\"\377"

.ascii "\202\202\202\377\377\377\377\377\263\263\263\377BBB\377\0\0\0\377...\377"

.ascii "\206\206\206\377\220\220\220\377\215\215\215\377<<<\377:::\377\377\377\377"

.ascii "\377\234\234\234\377\2\2\2\377+++\377\331\331\331\377\332\332\332\377)))"

.ascii "\377\6\6\6\377\215\215\215\377\377\377\377\377\377\377\377\377\206\206\206"

.ascii "\377333\377^^^\377\2\2\2\377\0\0\0\377\261\261\261\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\332\332\332\377555\377\313\313"

.ascii "\313\377\377\377\377\377\370\370\370\377SSS\377\1\1\1\377\227\227\227\377"

.ascii "\377\377\377\377\377\377\377\377\333\333\333\377\36\36\36\377\300\300\300"

.ascii "\377\376\376\376\377\325\325\325\377\0\0\0\377\0\0\0\377\305\305\305\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\353\353"

.ascii "\353\377888\377\23\23\23\377\7\7\7\377CCC\377\346\346\346\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\231\231\231\377@@@\377\370\370\370\377"

.ascii "\370\370\370\377\370\370\370\377\370\370\370\377\373\373\373\377\377\377"

.ascii "\377\377\377\377\377\377\376\376\376\377666\377\0\0\0\377\233\233\233\377"

.ascii "\374\374\374\377\355\355\355\377ooo\377\206\206\206\377\377\377\377\377\377"

.ascii "\377\377\377\374\374\374\377\370\370\370\377\370\370\370\377\370\370\370"

.ascii "\377\365\365\365\377\210\210\210\377\21\21\21\377\227\227\227\377\374\374"

.ascii "\374\377\377\377\377\377\354\354\354\377<<<\377\14\14\14\377\307\307\307"

.ascii "\377\376\376\376\377\232\232\232\377\0\0\0\377HHH\377\377\377\377\377\377"

.ascii "\377\377\377\254\254\254\377\17\17\17\377\11\11\11\377\311\311\311\377\375"

.ascii "\375\375\377\216\216\216\377\0\0\0\377\36\36\36\377\376\376\376\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\254\254\254\377\30\30\30\377\10"

.ascii "\10\10\377\1\1\1\377\261\261\261\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\307\307\307\377\4\4\4\377\0\0\0\377\352\352\352\377\377\377"

.ascii "\377\377\332\332\332\377!!!\377\12\12\12\377\240\240\240\377\377\377\377"

.ascii "\377\334\334\334\377555\377\0\0\0\377SSS\377\364\364\364\377\376\376\376"

.ascii "\377\346\346\346\377FFF\377bbb\377\377\377\377\377\346\346\346\377\0\0\0"

.ascii "\377\7\7\7\377\310\310\310\377\375\375\375\377\216\216\216\377\10\10\10\377"

.ascii "\24\24\24\377\262\262\262\377\377\377\377\377\377\377\377\377hhh\377\0\0"

.ascii "\0\377NNN\377\377\377\377\377\377\377\377\377\346\346\346\377RRR\377\220"

.ascii "\220\220\377\377\377\377\377\377\377\377\377vvv\377\0\0\0\377RRR\377\356"

.ascii "\356\356\377\377\377\377\377\372\372\372\377kkk\377:::\377\377\377\377\377"

.ascii "III\377\0\0\0\377EEE\377\374\374\374\377\357\357\357\377TTT\377\0\0\0\377"

.ascii "YYY\377\361\361\361\377\377\377\377\377\337\337\337\377\342\342\342\377\372"

.ascii "\372\372\377\5\5\5\377\0\0\0\377\261\261\261\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\365\365\365\377\312\312\312\377"

.ascii "\361\361\361\377\377\377\377\377\375\375\375\377YYY\377\1\1\1\377\227\227"

.ascii "\227\377\377\377\377\377\377\377\377\377\370\370\370\377\323\323\323\377"

.ascii "\366\366\366\377\377\377\377\377\356\356\356\377\0\0\0\377\3\3\3\377\312"

.ascii "\312\312\377\377\377\377\377\377\377\377\377\377\377\377\377\370\370\370"

.ascii "\377\210\210\210\377\36\36\36\377lll\377\24\24\24\377CCC\377\346\346\346"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\231\231\231\377BBB\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

Page 106: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

106

.ascii "\377\377\377\377\377\377\377\377\377\377\316\316\316\377\0\0\0\377\22\22"

.ascii "\22\377\356\356\356\377\377\377\377\377\375\375\375\377\360\360\360\377\361"

.ascii "\361\361\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\327\327\327\377222\377OOO\377\362\362"

.ascii "\362\377\377\377\377\377\377\377\377\377\352\352\352\377111\377\6\6\6\377"

.ascii "\217\217\217\377\373\373\373\377\241\241\241\377\0\0\0\377kkk\377\377\377"

.ascii "\377\377\377\377\377\377\177\177\177\377\2\2\2\377%%%\377\332\332\332\377"

.ascii "\377\377\377\377\270\270\270\377\0\0\0\377\0\0\0\377\320\320\320\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377eee\377PPP\377HHH\377\0\0\0\377"

.ascii "lll\377\377\377\377\377\377\377\377\377\377\377\377\377\307\307\307\377\4"

.ascii "\4\4\377\0\0\0\377\352\352\352\377\377\377\377\377\334\334\334\377&&&\377"

.ascii "\16\16\16\377\261\261\261\377\376\376\376\377\240\240\240\377\7\7\7\377\30"

.ascii "\30\30\377\271\271\271\377\377\377\377\377\377\377\377\377\357\357\357\377"

.ascii "```\377ppp\377\377\377\377\377\346\346\346\377\0\0\0\377\7\7\7\377\310\310"

.ascii "\310\377\377\377\377\377\327\327\327\377///\377\0\0\0\377vvv\377\371\371"

.ascii "\371\377\377\377\377\377hhh\377\0\0\0\377NNN\377\377\377\377\377\377\377"

.ascii "\377\377\372\372\372\377\335\335\335\377\351\351\351\377\377\377\377\377"

.ascii "\377\377\377\377vvv\377\0\0\0\377RRR\377\356\356\356\377\377\377\377\377"

.ascii "\376\376\376\377\330\330\330\377\314\314\314\377\377\377\377\377\34\34\34"

.ascii "\377\0\0\0\377sss\377\377\377\377\377\377\377\377\377{{{\377\0\0\0\377::"

.ascii ":\377\342\342\342\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\5\5\5\377\0\0\0\377\261\261\261\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\336\336\336\377777\377\24\24\24\377\264"

.ascii "\264\264\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\232\232\232\377\0\0\0\377EEE\377\376"

.ascii "\376\376\377\377\377\377\377\377\377\377\377\377\377\377\377\316\316\316"

.ascii "\377\33\33\33\377___\377\262\262\262\377\24\24\24\377CCC\377\346\346\346"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\231\231\231\377---\377"

.ascii "\246\246\246\377\307\307\307\377\370\370\370\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\223\223\223\377\0\0\0\377666\377"

.ascii "\331\331\331\377\223\223\223\377\200\200\200\377\306\306\306\377\375\375"

.ascii "\375\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377xxx\377\11\11\11\377\310\310\310\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\364\364\364\377```\377\0\0\0"

.ascii "\377\40\40\40\377\252\252\252\377777\377\23\23\23\377\321\321\321\377\377"

.ascii "\377\377\377\377\377\377\377www\377\0\0\0\377)))\377\334\334\334\377\377"

.ascii "\377\377\377\270\270\270\377\0\0\0\377\0\0\0\377\234\234\234\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377000\377|||\377\214\214\214\377\0"

.ascii "\0\0\377222\377\377\377\377\377\377\377\377\377\377\377\377\377\307\307\307"

.ascii "\377\4\4\4\377\0\0\0\377\352\352\352\377\377\377\377\377\214\214\214\377"

.ascii "\0\0\0\377:::\377\360\360\360\377\372\372\372\377jjj\377\0\0\0\377<<<\377"

.ascii "\346\346\346\377\377\377\377\377\377\377\377\377\374\374\374\377\343\343"

.ascii "\343\377\346\346\346\377\377\377\377\377\346\346\346\377\0\0\0\377\7\7\7"

.ascii "\377\310\310\310\377\377\377\377\377\363\363\363\377RRR\377\0\0\0\377FFF"

.ascii "\377\357\357\357\377\377\377\377\377hhh\377\0\0\0\377NNN\377\377\377\377"

.ascii "\377\277\277\277\377\230\230\230\377\360\360\360\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377vvv\377\0\0\0\377RRR\377\356\356\356\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\0\0\0\377\0\0\0\377|||\377\377\377\377\377\377\377\377\377{{{\377\0"

.ascii "\0\0\377'''\377\331\331\331\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\5\5\5\377\0\0\0\377\261\261\261\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\376\376\376\377\230\230\230\377\12\12\12\377UUU"

.ascii "\377\363\363\363\377\377\377\377\377\377\377\377\377\377\377\377\377\326"

.ascii "\326\326\377vvv\377<<<\377\20\20\20\377ccc\377\342\342\342\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\372\372\372\377[[[\377000\377\334\334"

.ascii "\334\377\262\262\262\377\24\24\24\377CCC\377\346\346\346\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\244\244\244\377\36\36\36\377\13\13\13"

.ascii "\377\15\15\15\377...\377\240\240\240\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377```\377\0\0\0\377111\377\40\40\40\377\4\4\4\377\1\1\1\377"

.ascii "\26\26\26\377\246\246\246\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\327\327\327\377\12\12\12\377aaa\377"

.ascii "\370\370\370\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\335\335\335\377888\377\0\0\0\377\12\12\12\377\12\12\12\377\223\223"

.ascii "\223\377\375\375\375\377\377\377\377\377\377\377\377\377\216\216\216\377"

.ascii "\7\7\7\377\4\4\4\377\272\272\272\377\377\377\377\377\216\216\216\377\0\0"

.ascii "\0\377\0\0\0\377\211\211\211\377\377\377\377\377\377\377\377\377\330\330"

.ascii "\330\377'''\377\255\255\255\377\327\327\327\377\5\5\5\377\22\22\22\377\345"

.ascii "\345\345\377\377\377\377\377\377\377\377\377\307\307\307\377\4\4\4\377\0"

Page 107: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

107

.ascii "\0\0\377ggg\377777\377\14\14\14\377<<<\377\316\316\316\377\377\377\377\377"

.ascii "\364\364\364\377999\377\0\0\0\377QQQ\377\375\375\375\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\346\346\346\377\0\0\0\377\7\7\7\377\310\310\310\377\377\377\377"

.ascii "\377\377\377\377\377bbb\377\0\0\0\377000\377\352\352\352\377\377\377\377"

.ascii "\377hhh\377\0\0\0\377'''\377~~~\377BBB\377999\377\341\341\341\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377vvv\377\0\0\0\377JJJ\377\326\326"

.ascii "\326\377\252\252\252\377111\377\316\316\316\377\377\377\377\377\377\377\377"

.ascii "\377\0\0\0\377\0\0\0\377|||\377\377\377\377\377\377\377\377\377{{{\377\0"

.ascii "\0\0\377'''\377\331\331\331\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\5\5\5\377\0\0\0\377\261\261\261\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\345\345\345\377\30\30\30\377$$$\377\331\331\331"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\306"

.ascii "\306\306\377:::\377\24\24\24\377\11\11\11\377JJJ\377\270\270\270\377\377"

.ascii "\377\377\377\377\377\377\377\376\376\376\377\247\247\247\377\27\27\27\377"

.ascii "\223\223\223\377\374\374\374\377\262\262\262\377\24\24\24\377CCC\377\346"

.ascii "\346\346\377\377\377\377\377\377\377\377\377\377\377\377\377\352\352\352"

.ascii "\377\311\311\311\377\254\254\254\377000\377\0\0\0\377\27\27\27\377\303\303"

.ascii "\303\377\377\377\377\377\377\377\377\377OOO\377\0\0\0\377\0\0\0\377@@@\377"

.ascii "\240\240\240\377(((\377\0\0\0\377,,,\377\350\350\350\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\374\374\374\377iii\377\25\25\25\377\262"

.ascii "\262\262\377\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\376\376\376\377\303\303\303\377,,,\377\16\16\16\377\10\10\10\377\3\3"

.ascii "\3\377000\377\304\304\304\377\376\376\376\377\377\377\377\377\321\321\321"

.ascii "\377\37\37\37\377\0\0\0\377111\377sss\377###\377\2\2\2\377\0\0\0\377\211"

.ascii "\211\211\377\377\377\377\377\377\377\377\377\245\245\245\377+++\377\321\321"

.ascii "\321\377\345\345\345\377(((\377\11\11\11\377\247\247\247\377\377\377\377"

.ascii "\377\377\377\377\377\307\307\307\377\4\4\4\377\0\0\0\377\24\24\24\377\20"

.ascii "\20\20\377\5\5\5\377333\377\271\271\271\377\376\376\376\377\364\364\364\377"

.ascii "555\377\0\0\0\377RRR\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\346\346"

.ascii "\346\377\0\0\0\377\7\7\7\377\310\310\310\377\377\377\377\377\377\377\377"

.ascii "\377bbb\377\0\0\0\377000\377\352\352\352\377\377\377\377\377hhh\377\0\0\0"

.ascii "\377\5\5\5\377\17\17\17\377\10\10\10\377999\377\341\341\341\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377vvv\377\0\0\0\377\21\21\21\377000\377"

.ascii "%%%\377\16\16\16\377\312\312\312\377\377\377\377\377\377\377\377\377\0\0"

.ascii "\0\377\0\0\0\377|||\377\377\377\377\377\377\377\377\377{{{\377\0\0\0\377"

.ascii "'''\377\331\331\331\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\5\5\5\377\0\0\0\377\261\261\261\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\352\352\352\377QQQ\377\40\40\40\377\275\275\275\377\376\376\376\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\363\363\363\377\222\222\222\377\11\11\11\377\12\12\12"

.ascii "\377\330\330\330\377\377\377\377\377\343\343\343\377???\377\24\24\24\377"

.ascii "www\377\205\205\205\377]]]\377\12\12\12\377###\377zzz\377\344\344\344\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\320\320\320\377\25\25\25\377\2\2\2\377kkk\377\370\370\370\377\377"

.ascii "\377\377\377OOO\377\0\0\0\377\0\0\0\377\323\323\323\377\377\377\377\377\254"

.ascii "\254\254\377\0\0\0\377\21\21\21\377\264\264\264\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\304\304\304\377\35\35\35\377MMM\377\364\364\364"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\353"

.ascii "\353\353\377999\377\14\14\14\377\304\304\304\377\235\235\235\377\11\11\11"

.ascii "\377\0\0\0\377,,,\377\330\330\330\377\377\377\377\377\377\377\377\377\237"

.ascii "\237\237\377\25\25\25\377\0\0\0\377\14\14\14\377hhh\377\33\33\33\377\0\0"

.ascii "\0\377\245\245\245\377\377\377\377\377\377\377\377\377www\377$$$\377\256"

.ascii "\256\256\377\243\243\243\377777\377\3\3\3\377xxx\377\377\377\377\377\377"

.ascii "\377\377\377\307\307\307\377\4\4\4\377\0\0\0\377\347\347\347\377\330\330"

.ascii "\330\377ppp\377\0\0\0\377\22\22\22\377\301\301\301\377\365\365\365\377=="

.ascii "=\377\0\0\0\377JJJ\377\365\365\365\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\346\346\346"

.ascii "\377\0\0\0\377\7\7\7\377\310\310\310\377\377\377\377\377\377\377\377\377"

.ascii "bbb\377\0\0\0\377777\377\353\353\353\377\377\377\377\377hhh\377\0\0\0\377"

.ascii "AAA\377\323\323\323\377nnn\377999\377\341\341\341\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377vvv\377\0\0\0\377\32\32\32\377LLL\377:::\377"

.ascii "\21\21\21\377\312\312\312\377\377\377\377\377\377\377\377\377'''\377\0\0"

.ascii "\0\377mmm\377\377\377\377\377\373\373\373\377ppp\377\0\0\0\377AAA\377\346"

.ascii "\346\346\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\5\5\5\377\0\0\0\377\261\261\261\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\373\373\373\377~~~\377\15"

Page 108: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

108

.ascii "\15\15\377\253\253\253\377\373\373\373\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\366\366\366\377KKK\377\0\0\0\377ggg\377\377\377"

.ascii "\377\377\324\324\324\377%%%\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0"

.ascii "\0\0\377\0\0\0\377\4\4\4\377\307\307\307\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\356\356\356\377RRR\377"

.ascii "\0\0\0\377KKK\377\352\352\352\377\377\377\377\377vvv\377\0\0\0\377\0\0\0"

.ascii "\377\362\362\362\377\377\377\377\377\312\312\312\377\0\0\0\377\15\15\15\377"

.ascii "\244\244\244\377\377\377\377\377\377\377\377\377\373\373\373\377ccc\377\1"

.ascii "\1\1\377\220\220\220\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\235\235\235\377\2\2\2\377999\377\375\375"

.ascii "\375\377\374\374\374\377\225\225\225\377\13\13\13\377\3\3\3\377\233\233\233"

.ascii "\377\377\377\377\377\377\377\377\377\373\373\373\377\333\333\333\377\263"

.ascii "\263\263\377\315\315\315\377\351\351\351\377\5\5\5\377\0\0\0\377\323\323"

.ascii "\323\377\377\377\377\377\350\350\350\377HHH\377\2\2\2\377\13\13\13\377\13"

.ascii "\13\13\377\4\4\4\377\0\0\0\377FFF\377\350\350\350\377\377\377\377\377\307"

.ascii "\307\307\377\4\4\4\377\0\0\0\377\352\352\352\377\377\377\377\377\344\344"

.ascii "\344\377:::\377\1\1\1\377bbb\377\360\360\360\377nnn\377\0\0\0\377111\377"

.ascii "\332\332\332\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\346\346\346\377\0\0\0\377\7\7\7"

.ascii "\377\310\310\310\377\377\377\377\377\351\351\351\377EEE\377\0\0\0\377ccc"

.ascii "\377\365\365\365\377\377\377\377\377hhh\377\0\0\0\377NNN\377\377\377\377"

.ascii "\377\327\327\327\377\275\275\275\377\365\365\365\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377vvv\377\0\0\0\377OOO\377\343\343\343\377\301"

.ascii "\301\301\377YYY\377\327\327\327\377\377\377\377\377\377\377\377\377VVV\377"

.ascii "\0\0\0\377AAA\377\375\375\375\377\355\355\355\377PPP\377\0\0\0\377aaa\377"

.ascii "\365\365\365\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\5\5\5\377\0\0\0\377\261\261\261\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\322\322\322\377\22\22"

.ascii "\22\377MMM\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\365\365\365\377\300\300\300\377\362"

.ascii "\362\362\377\377\377\377\377\373\373\373\377kkk\377\0\0\0\377OOO\377\377"

.ascii "\377\377\377\360\360\360\377\263\263\263\377\246\246\246\377\246\246\246"

.ascii "\377\246\246\246\377ttt\377\15\15\15\377,,,\377\230\230\230\377\354\354\354"

.ascii "\377\377\377\377\377\377\377\377\377\331\331\331\377\333\333\333\377\377"

.ascii "\377\377\377\360\360\360\377VVV\377\0\0\0\377KKK\377\352\352\352\377\377"

.ascii "\377\377\377\245\245\245\377\0\0\0\377\0\0\0\377\360\360\360\377\377\377"

.ascii "\377\377\311\311\311\377\0\0\0\377\20\20\20\377\260\260\260\377\377\377\377"

.ascii "\377\377\377\377\377\347\347\347\377\15\15\15\377\1\1\1\377\333\333\333\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377jjj\377\0\0\0\377JJJ\377\377\377\377\377\377\377\377\377\334\334"

.ascii "\334\377555\377\1\1\1\377\230\230\230\377\377\377\377\377\377\377\377\377"

.ascii "\366\366\366\377\371\371\371\377\377\377\377\377\377\377\377\377\310\310"

.ascii "\310\377\0\0\0\377\34\34\34\377\376\376\376\377\377\377\377\377\325\325\325"

.ascii "\377'''\377|||\377\246\246\246\377\246\246\246\377uuu\377\16\16\16\377))"

.ascii ")\377\324\324\324\377\377\377\377\377\307\307\307\377\4\4\4\377\0\0\0\377"

.ascii "\352\352\352\377\377\377\377\377\360\360\360\377VVV\377\0\0\0\377JJJ\377"

.ascii "\351\351\351\377\241\241\241\377\7\7\7\377\12\12\12\377\235\235\235\377\376"

.ascii "\376\376\377\377\377\377\377\377\377\377\377\377\377\377\377\376\376\376"

.ascii "\377\377\377\377\377\346\346\346\377\0\0\0\377\7\7\7\377\310\310\310\377"

.ascii "\377\377\377\377\323\323\323\377+++\377\6\6\6\377\224\224\224\377\376\376"

.ascii "\376\377\377\377\377\377hhh\377\0\0\0\377NNN\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\267\267\267\377zzz\377\351\351\351\377\377\377\377"

.ascii "\377vvv\377\0\0\0\377RRR\377\356\356\356\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\254\254\254\377\11\11"

.ascii "\11\377\37\37\37\377\306\306\306\377\317\317\317\377\35\35\35\377\13\13\13"

.ascii "\377\240\240\240\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\5\5\5\377\0\0\0\377\261\261\261\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\364\364\364\377"

.ascii "OOO\377\12\12\12\377\240\240\240\377\332\332\332\377\332\332\332\377\332"

.ascii "\332\332\377\360\360\360\377\377\377\377\377\377\377\377\377\326\326\326"

.ascii "\377\0\0\0\377\301\301\301\377\377\377\377\377\356\356\356\377)))\377\0\0"

.ascii "\0\377{{{\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\262\262\262\377\24\24\24\377CCC\377"

.ascii "\346\346\346\377\377\377\377\377\377\377\377\377\377\377\377\377fff\377:"

.ascii "::\377\377\377\377\377\326\326\326\377!!!\377\4\4\4\377\203\203\203\377\377"

.ascii "\377\377\377\377\377\377\377\363\363\363\377\21\21\21\377\0\0\0\377\251\251"

.ascii "\251\377\377\377\377\377\213\213\213\377\0\0\0\377(((\377\345\345\345\377"

.ascii "\377\377\377\377\377\377\377\377\227\227\227\377\0\0\0\377$$$\377\374\374"

.ascii "\374\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

Page 109: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

109

.ascii "\377\377\377\377\203\203\203\377\0\0\0\377\15\15\15\377\322\322\322\377\377"

.ascii "\377\377\377\301\301\301\377!!!\377\32\32\32\377\275\275\275\377\377\377"

.ascii "\377\377\377\377\377\377&&&\377hhh\377\367\367\367\377\345\345\345\377II"

.ascii "I\377\5\5\5\377\206\206\206\377\377\377\377\377\377\377\377\377\255\255\255"

.ascii "\377\16\16\16\377\344\344\344\377\377\377\377\377\377\377\377\377\343\343"

.ascii "\343\377,,,\377\7\7\7\377\263\263\263\377\377\377\377\377\307\307\307\377"

.ascii "\4\4\4\377\0\0\0\377\352\352\352\377\377\377\377\377\332\332\332\377///\377"

.ascii "\0\0\0\377UUU\377\360\360\360\377\347\347\347\377CCC\377\0\0\0\377\25\25"

.ascii "\25\377\263\263\263\377\365\365\365\377\372\372\372\377\323\323\323\377\236"

.ascii "\236\236\377\377\377\377\377\346\346\346\377\0\0\0\377\7\7\7\377\310\310"

.ascii "\310\377\367\367\367\377ddd\377\0\0\0\377888\377\343\343\343\377\377\377"

.ascii "\377\377\377\377\377\377hhh\377\0\0\0\377NNN\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\220\220\220\377333\377\335\335\335\377\377\377\377"

.ascii "\377vvv\377\0\0\0\377RRR\377\356\356\356\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\351\351\351\377UUU\377"

.ascii "\4\4\4\377222\377111\377\2\2\2\377LLL\377\364\364\364\377\377\377\377\377"

.ascii "\377\377\377\377\261\261\261\377```\377```\377\2\2\2\377\0\0\0\377CCC\377"

.ascii "```\377}}}\377\377\377\377\377\377\377\377\377\334\334\334\377+++\377\4\4"

.ascii "\4\377\30\30\30\377\36\36\36\377\36\36\36\377\36\36\36\377\242\242\242\377"

.ascii "\377\377\377\377\377\377\377\377\326\326\326\377\0\0\0\377%%%\377```\377"

.ascii "555\377\2\2\2\377///\377\341\341\341\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\311\311\311\377iii\377CCC\377\10\10\10\377"

.ascii "\31\31\31\377[[[\377\377\377\377\377\377\377\377\377\377\377\377\377fff\377"

.ascii "\16\16\16\377QQQ\377555\377\0\0\0\377222\377\344\344\344\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\213\213\213\377\16\16\16\377\37\37\37"

.ascii "\377OOO\377\26\26\26\377\12\12\12\377\216\216\216\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377PPP\377\0\0\0\377EEE\377\374\374\374\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\335\335\335\377(((\377\3\3\3\377!!!\377UUU\377(((\377\6\6\6\377ooo\377"

.ascii "\367\367\367\377\377\377\377\377\377\377\377\377&&&\377\27\27\27\377TTT\377"

.ascii "666\377\7\7\7\377SSS\377\342\342\342\377\377\377\377\377\377\377\377\377"

.ascii "???\377\20\20\20\377xxx\377\377\377\377\377\370\370\370\377\230\230\230\377"

.ascii "\25\25\25\377\0\0\0\377;;;\377\355\355\355\377ooo\377\2\2\2\377\0\0\0\377"

.ascii "XXX\377```\377)))\377\3\3\3\377\21\21\21\377\246\246\246\377\376\376\376"

.ascii "\377\377\377\377\377\327\327\327\377\37\37\37\377\2\2\2\377\20\20\20\377"

.ascii "(((\377***\377\33\33\33\377///\377\377\377\377\377yyy\377\0\0\0\377\3\3\3"

.ascii "\377LLL\377FFF\377\6\6\6\377\35\35\35\377\276\276\276\377\377\377\377\377"

.ascii "\365\365\365\377\225\225\225\377(((\377\0\0\0\377\36\36\36\377```\377```"

.ascii "\377```\377777\377111\377\335\335\335\377\223\223\223\377,,,\377\0\0\0\377"

.ascii "\37\37\37\377fff\377\341\341\341\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\334\334\334\377[[[\377\17\17"

.ascii "\17\377\12\12\12\377```\377\334\334\334\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\202\202\202\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377"

.ascii "\0\0\0\377\0\0\0\377...\377\377\377\377\377\377\377\377\377\332\332\332\377"

.ascii "***\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\225\225\225\377"

.ascii "\377\377\377\377\377\377\377\377\344\344\344\377FFF\377\27\27\27\377\0\0"

.ascii "\0\377\33\33\33\377bbb\377\325\325\325\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\251\251\251\377\17\17\17"

.ascii "\377\0\0\0\377\0\0\0\377\0\0\0\377\7\7\7\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\244\244\244\377,,,\377\0\0\0\377\30\30\30\377ggg\377"

.ascii "\321\321\321\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\364\364\364\377\236\236\236\377\36\36\36\377\0\0\0\377***\377\214"

.ascii "\214\214\377\364\364\364\377\377\377\377\377\377\377\377\377\361\361\361"

.ascii "\377===\377\0\0\0\377rrr\377\376\376\376\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\376\376\376\377\322"

.ascii "\322\322\377ZZZ\377\25\25\25\377\1\1\1\377...\377\204\204\204\377\364\364"

.ascii "\364\377\377\377\377\377\377\377\377\377\377\377\377\377jjj\377\33\33\33"

.ascii "\377\0\0\0\377\26\26\26\377lll\377\352\352\352\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\17\17\17\377\0\0\0\377333\377\377\377\377\377\363"

.ascii "\363\363\377\\\\\\\377\0\0\0\377\0\0\0\377\10\10\10\377\342\342\342\377:"

.ascii "::\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\11\11\11\377EEE\377\240\240"

.ascii "\240\377\371\371\371\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\324\324\324\377sss\377\34\34\34\377\0\0\0\377\13\13\13\377FFF\377\250\250"

.ascii "\250\377\377\377\377\377777\377\0\0\0\377\0\0\0\377\0\0\0\377###\377nnn\377"

.ascii "\320\320\320\377\375\375\375\377\377\377\377\377\357\357\357\377TTT\377\0"

.ascii "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377000\377"

.ascii "\335\335\335\377QQQ\377\0\0\0\377\0\0\0\377\0\0\0\377\23\23\23\377\316\316"

.ascii "\316\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

Page 110: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

110

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"

.ascii "\377\377\377\377\377\377\377\377\377\377",

Page 111: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

111

BIBLIOGRAFIA

1. Intel PXA255 Processor – Developer’s Manual (278693-001.pdf)

2. Intel PXA255 Processor – Design Guide (278694-001.pdf)

3. Intel PXA255 Processor – Specification update (278732-002.pdf)

4. ARM Architecture Reference Manual (ddi0100e_arm_arm.pdf)

5. XScale_architecture.pdf

6. Intel XScale Core – Developer’s Manual - (273471-001.pdf)

7. ARM9TDMI – Technical Reference Manual – (ddi0180a_9tdmi_trm.pdf)

8. GNUPro Toolkit user guide – gnupro_userguide.pdf

Page 112: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

112

APPENDICE

Page 113: LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI …unina.stidue.net/Calcolatori Elettronici 2/Materiale/Sergio Congiu... · LABORATORIO DI ARCHITETTURA DEGLI ELABORATORI UNI-PD-PXA

113

Tabella rimappatura memoria La MMU viene abilitata col bit 0 del registro 1 del Coprocessore 15 dell’Xscale Core.

NOTA: l’indirizzo di memoria 0xA0000000 è stato riallocato in due zone distinte, ognuna con attri-buti diversi.

Actual base

xxx00000

Virtual base

xxx00000

Size at-tribute (MB)

Cached Buffered Access pemission What

000 500 64 NO NO RW FLASH EPROM 040 600 64 NO NO RW RAM STATICA 080 640 64 NO NO RW Servizi interni (Vedi U14) 0C0 680 64 NO NO RW BUS DI ESPANSIONE 100 6C0 64 NO NO RW CS[4]=

140 700 64 NO NO RW LED FRONTALI / SWITCHES

400 400 192 NO NO RW Memory mapped registers

(Peripherals, LCD & Memory Controller )

A00 0 64 SI NO RW Sdram bank0 A00 A00 256 NO NO RW Unmapped memory C00 C00 128 SI SI RW - reserved -