Università degli Studi di Udine Corsi di laurea in Ingegneria
Transcript
Università degli Studi di Udine Corsi di laurea in Ingegneria
Università degli Studi di Udine Corsi di laurea in Ingegneria Elettronica Architettura dei calcolatori (ex Fondamenti di Informatica II) 28 giugno 2011 - Prova scritta 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 un floppy disk contenente i sorgenti dei programmi corretti e le stampe dei relativi file. 2) Non è consentito l’uso di libri, appunti, calcolatrici programmabili, telefoni cellulari. 3) Rispondere sinteticamente negli spazi di fianco o seguenti le domande, oppure sul retro del foglio. 1. (3 punti) Si svolga, utilizzando la rappresentazione in complemento a 2 su 16 bit, l’operazione 409610 – 409510, riportando nel dettaglio tutti i passaggi. 2. (3 punti) Cos’è e come si calcola un CRC? 3. (2 punti) Cosa significa “codifica entropica”? Si consideri una libreria in linguaggio C per manipolare file audio così definita: typedef typedef typedef unsigned char unsigned short int unsigned long int byte; word; dword; #define SAMPLE(wave, channel, offset) \ wave.wavedata.sample \ [2 * (offset) + (channel)] #define #define #define #define #define #define #define #define #define #define FMTPCM 1 SAMPLINGRATE 44100 CHANNELS 2 BITSPERSAMPLE 16 LEFT 0 RIGHT 1 RIFF_ID "RIFF" WAV_ID "WAVE" FMT_ID "fmt " DATA_ID "data" typedef struct tagRIFFHEADER { char riffid[4]; dword FileSize; char waveid[4]; } RIFFHEADER; typedef struct tagWAVEDATA { char dataid[4]; dword DataSize; signed short int *sample; } WAVEDATA; typedef struct tagFMTHEADER { char fmtid[4]; dword fmtsize; word format; word channels; dword SampleRate; dword BytesPerSecond; word BlockAlign; word BitsPerSample; } FMTHEADER; typedef struct tagWAVE { RIFFHEADER riffheader; FMTHEADER fmtheader; unsigned long int numofstereosamples; WAVEDATA wavedata; } WAVE; void WAVE WAVE void WriteWave (WAVE wave, FILE *fp); ReadWave (FILE *fp); CreateEmptyCDaudioWave (unsigned long int numofstereosamples); ReleaseWaveData (WAVE *wave); 4. (8 punti) Volete riprodurre, tramite la scheda audio del vostro computer, il contenuto di due file audio stereo in formato standard WAV (44.100 campioni/secondo, 16 bit per campione). Il primo file contiene del parlato mentre il secondo file contiene della musica da usare come sottofondo del parlato. I due file hanno durata differente e, se quella della musica di sottofondo è inferiore a quella del parlato, la riproduzione della musica deve ripartire dall’inizio ed essere ripetuta per quante volte è necessario per arrivare fino alla fine del parlato. La riproduzione simultanea dei due file audio avviene semplicemente miscelandoli in proporzioni uguali, cioè effettuando la media dei valori dei campioni provenienti dai due file. Periodicamente il driver della scheda audio chiama la funzione void load_buffer (signed short int *sample, int dim) per “richiedere” al programma i campioni audio da riprodurre. La funzione riceve come argomenti un vettore di campioni (da riempire) e la sua dimensione (sempre pari, corrispondente a un numero intero di campioni stereo). Nel vettore i campioni stereo sono alternati: quelli di indice pari corrispondono al canale di sinistra e quelli dispari a quello di destra. Supponendo che il programma preveda le seguenti variabili globali: int posizione_parlato = 0; int posizione_musica = 0; WAVE audio_parlato; WAVE audio_musica; e che le due strutture di tipo WAVE siano già state caricate (ad opera del main) con il contenuto dei due file audio in oggetto, si scriva la funzione load_buffer. Il valore dei campioni successivi all’ultimo del parlato devono essere posti a zero. (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: assembly inst. name machine code LDWI LDWA LDWR LDBI LDBA LDBR STWA STWR STBA STBR MV PUSH POP SPRD SPWR load word load word load word load byte load byte load byte store word store word store byte store byte move push pop read SP write SP 00010000dddd0000 00100000dddd0000 00110000ddddaaaa 00010001dddd0000 00100001dddd0000 00110001ddddaaaa 00100010ssss0000 00110010ssssaaaa 00100011ssss0000 00110011ssssaaaa 00000100ssssdddd 00001000ssss0000 00001001dddd0000 00001101ssss0000 00001110ssss0000 add subtract bitwise NOT bitwise AND bitwise OR bitwise XOR increment decrement left shift right shift 01000000ssssdddd 01000001ssssdddd 01000010rrrr0000 01000011ssssdddd 01000100ssssdddd 01000101ssssdddd 01001000rrrr0000 01001001rrrr0000 01001010rrrr0000 01001011rrrr0000 ADD SUB NOT AND OR XOR INC DEC LSH RSH 5. d d d d d d s s s s s s d d s s s r s s s r r r r X A a X A a A a A a d d d d d d DATA(16) ADDR(16) DATA(8) ADDR(16) ADDR(16) ADDR(16) action assembly inst. name machine code d <- X d <- mem[A] d <- mem[a] d <- X d <- mem[A] d <- mem[a] mem[A] <- s mem[a] <- s mem[A] <- s mem[a] <- s d <- s push (s) d <- pop () d <- SP SP <- s INW INB OUTW OUTB TSTI 10000000dddd0000 10000001dddd0000 10000010ssss0000 10000011ssss0000 1000010000000000 d d r d d d r r r r <<<<<<<<<<- d + s d - s ~r d & s d | s d ^ s r + 1 r + 1 r << 1 r >> 1 d d s s A A A A A input word input byte out word out byte test input action IN_ADDR(16) IN_ADDR(16) OUT_ADDR(16) OUT_ADDR(16) IN_ADDR(16) TSTO A test output 1000010100000000 OUT_ADDR(16) BR JMP JMPZ JMPNZ JMPN JMPNN JMPC JMPV CALL RET HLT branch jump jump if zero jump if not zero jump if negative jump if not neg. jump if carry jump if overflow subroutine call return from sub. halt A F F F F F F F A d <- read[A] d <- read[A] out[A] <- s out[A] <- s if completed then Z <- 1 else Z <- 0 if completed then Z <- 1 else Z <- 0 1100000000000000 ADDR(16) PC <- A 11000001FFFFFFFF PC <- PC + F 11000010FFFFFFFF if (z == 1) PC <- PC 11000011FFFFFFFF if (z == 0) PC <- PC 11000100FFFFFFFF if (N == 1) PC <- PC 11000101FFFFFFFF if (N == 0) PC <- PC 11000110FFFFFFFF if (C == 1) PC <- PC 11000111FFFFFFFF if (V == 1) PC <- PC 1100100000000000 ADDR(16) push (PC); PC <- A 1100100100000000 PC <- pop() 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) (10 punti) Si scriva in linguaggio assembler la funzione DIVISIBILE che riceve in R1 ed R2 due numeri interi positivi e che restituisce in R0 il valore 1 se R1 è divisibile per R2, zero altrimenti. (svolgere sul retro) 6. (4 punti) Si descrivano i supporti di memoria di massa magnetici e ottici e se ne giustifichino le differenze. (svolgere sul retro) 7. (2 punti) Si discuta il significato e l’utilizzo del simbolo ‘$’ nelle espressioni di calcolo in un foglio elettronico. + + + + + + F F F F F F