Università degli Studi di Udine
Architettura dei calcolatori / Fondamenti di Informatica II (prof. Montessoro) 5 febbraio 2018
Prova scritta per studenti di Ing. Elettronica e Ing. Gestionale immatricolati negli anni accademici 2016-17 e precedenti – DURATA DELLA PROVA: 2 ORE
Matricola __________________
Nome _____________________
Cognome __________________
ISTRUZIONI (da leggere attentamente)
1) Lo studente è tenuto a scrivere, correggere, compilare ed eseguire su computer (a casa o in laboratorio) gli esercizi di programmazione prima della prova orale. Alla prova orale lo studente deve portare una memory pen USB contenente i sorgenti dei programmi corretti e le stampe dei relativi file.
2) Non è consentito l’uso di libri, appunti, calcolatrici, telefoni cellulari.
3) Rispondere sinteticamente negli spazi di fianco o seguenti le domande, oppure sul retro del foglio.
1. (3 punti) Illustrare, con un esempio numerico, la codifica floating point in singola precisione.
2. (2 punti) X
16+X
15+X
2+1 rappresenta:
[ ] uno schema di memorizzazione dei bit ridondanti nella codifica di Hamming [ ] una funzione di compressione senza perdita
[ ] una funzione di compressione con perdita [ ] un polinomio generatore per il CRC
Si consideri una libreria in linguaggio C per manipolare file audio così definita:
typedef unsigned char byte;
typedef unsigned short int word;
typedef unsigned long int dword;
#define SAMPLE(wave, channel, offset) \ wave.wavedata.sample \ [2 * (offset) + (channel)]
#define FMTPCM 1
#define SAMPLINGRATE 44100
#define CHANNELS 2
#define BITSPERSAMPLE 16
#define LEFT 0
#define RIGHT 1
#define RIFF_ID "RIFF"
#define WAV_ID "WAVE"
#define FMT_ID "fmt "
#define DATA_ID "data"
typedef struct tagRIFFHEADER {
char riffid[4];
dword FileSize;
char waveid[4];
} RIFFHEADER;
typedef struct tagFMTHEADER {
char fmtid[4];
dword fmtsize;
word format;
word channels;
dword SampleRate;
dword BytesPerSecond;
word BlockAlign;
word BitsPerSample;
} FMTHEADER;
typedef struct tagWAVEDATA {
char dataid[4];
dword DataSize;
signed short int *sample;
} WAVEDATA;
typedef struct tagWAVE {
RIFFHEADER riffheader;
FMTHEADER fmtheader;
unsigned long int numofstereosamples;
WAVEDATA wavedata;
} WAVE;
void WriteWave (WAVE wave, FILE *fp);
WAVE ReadWave (FILE *fp);
WAVE CreateEmptyCDaudioWave (unsigned long int numofstereosamples);
void ReleaseWaveData (WAVE *wave);
3. (10 punti) Per amplificare un suono senza incorrere nell’overflow è necessario conoscere in anticipo il massimo valore di amplificazione utilizzabile. Si scriva un programma in linguaggio C che riceva come argomento sulla riga di comando il nome di un file WAVE e stampi il massimo valore del coefficiente di amplificazione che si può utilizzare senza che si verifichi overflow.
Suggerimento: il massimo valore di amplificazione utilizzabile è il rapporto tra il massimo valore rappresentabile per un campione e il massimo valore presente nella forma d’onda tra i campioni di entrambi i canali.
(svolgere sul retro)
Un elaboratore (il modello didattico SimCPU visto a lezione) dispone di CPU (a 16 bit) con 16 registri di uso generale (R0, R1, ..., R15) più il Program Counter, l’Instruction Register, lo Stack Pointer e 4 flag Z (zero), N (negative), C (carry) e V (overflow).
Si ricorda che il linguaggio assembler di tale elaboratore dispone delle seguenti istruzioni:
4. (5 punti) Assumendo che i nomi delle variabili corrispondano ai nomi dei registri della CPU, si traduca in linguaggio assembly il seguente frammento di codice C:
R0 = 0;
while ((R10 = *R1) != 0) {
R1++;
R0++;
}
5. (2 punti) Se R1 è l’indirizzo di una stringa, cosa fa il segmento di programma dell’esercizio precedente?
6. (6 punti) Si disegni lo schema di una memoria cache a mappatura diretta e se ne spieghi il funzionamento con un esempio numerico ipotizzando, per semplicità, indirizzi di memoria scritti su otto bit, blocchi da 16 byte e linee da quattro byte.
7. (2 punti) Cos’è e a cosa serve la MMU?
assembly inst. name machine code action LDWI d X load word 00010000dddd0000 DATA(16) d <- X LDWA d A load word 00100000dddd0000 ADDR(16) d <- mem[A]
LDWR d a load word 00110000ddddaaaa d <- mem[a]
LDBI d X load byte 00010001dddd0000 DATA(8) d <- X LDBA d A load byte 00100001dddd0000 ADDR(16) d <- mem[A]
LDBR d a load byte 00110001ddddaaaa d <- mem[a]
STWA s A store word 00100010ssss0000 ADDR(16) mem[A] <- s STWR s a store word 00110010ssssaaaa mem[a] <- s STBA s A store byte 00100011ssss0000 ADDR(16) mem[A] <- s STBR s a store byte 00110011ssssaaaa mem[a] <- s MV s d move 00000100ssssdddd d <- s PUSH s push 00001000ssss0000 push (s) POP d pop 00001001dddd0000 d <- pop () SPRD d read SP 00001101ssss0000 d <- SP SPWR s write SP 00001110ssss0000 SP <- s ADD s d add 01000000ssssdddd d <- d + s SUB s d subtract 01000001ssssdddd d <- d - s NOT r bitwise NOT 01000010rrrr0000 r <- ~r AND s d bitwise AND 01000011ssssdddd d <- d & s OR s d bitwise OR 01000100ssssdddd d <- d | s XOR s d bitwise XOR 01000101ssssdddd d <- d ^ s INC r increment 01001000rrrr0000 r <- r + 1 DEC r decrement 01001001rrrr0000 r <- r + 1 LSH r left shift 01001010rrrr0000 r <- r << 1 RSH r right shift 01001011rrrr0000 r <- r >> 1
assembly inst. name machine code action INW d A input word 10000000dddd0000 IN_ADDR(16) d <- read[A]
INB d A input byte 10000001dddd0000 IN_ADDR(16) d <- read[A]
OUTW s A out word 10000010ssss0000 OUT_ADDR(16) out[A] <- s OUTB s A out byte 10000011ssss0000 OUT_ADDR(16) out[A] <- s
TSTI A test input 1000010000000000 IN_ADDR(16) if completed then Z <- 1 else Z <- 0
TSTO A test output 1000010100000000 OUT_ADDR(16) if completed then Z <- 1 else Z <- 0
BR A branch 1100000000000000 ADDR(16) PC <- A JMP F jump 11000001FFFFFFFF PC <- PC + F
JMPZ F jump if zero 11000010FFFFFFFF if (z == 1) PC <- PC + F JMPNZ F jump if not zero 11000011FFFFFFFF if (z == 0) PC <- PC + F JMPN F jump if negative 11000100FFFFFFFF if (N == 1) PC <- PC + F JMPNN F jump if not neg. 11000101FFFFFFFF if (N == 0) PC <- PC + F JMPC F jump if carry 11000110FFFFFFFF if (C == 1) PC <- PC + F JMPV F jump if overflow 11000111FFFFFFFF if (V == 1) PC <- PC + F CALL A subroutine call 1100100000000000 ADDR(16) push (PC); PC <- A RET return from sub. 1100100100000000 PC <- pop() HLT halt 1100111100000000 halt LEGENDA:
- lettere minuscole = registri; lettere maiuscole = dati numerici - ‘r’ = registro letto e modificato
- ‘s’ = registro soltanto letto - ‘d’ = registro modificato
- ‘a’ = registro il cui contenuto è usato come indirizzo - FFFFFFFF = offset (in complemento a 2)