Università degli Studi di Udine
Corsi di laurea in Ingegneria Elettronica
Architettura dei calcolatori (ex Fondamenti di Informatica II) 24 gennaio 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. (4 punti) L’istruzione printf ("%X", *((int*)&x)) stampa in esadecimale il contenuto della memoria all’indirizzo dove è memorizzata la variabile float x, senza interpretarne la rappresentazione floating point. Il risultato ottenuto è BD400000. Ricordando che la rappresentazione dell’esponente è in eccesso 127, cosa stamperebbe l’istruzione printf ("%f", x)? Si scrivano tutti i passaggi e i calcoli effettuati.
segno (-)
B D 4 0 0 0 0 0 1011 1101 0100 0000 0000 0000 0000 0000
esponente mantissa (1.1
2= 1.5
10denormalizzata)
calcolo del valore dell’esponente:
01111010
2= 112
eccesso 127= 122-127 = -5
calcolo del valore della variabile:
-1.5 · 2
-5= -1.5 * 0.3125 = -0.046875
2. (4 punti) Si illustri brevemente la codifica entropica.
(si vedano il libro di testo, gli appunti e i lucidi delle lezioni)
Si consideri la libreria in linguaggio C per manipolare file bitmap vista a lezione, così definita:
typedef unsigned char byte;
typedef unsigned short int word;
typedef unsigned long int dword;
#define BMPFILETYPE 0x4D42
typedef struct tagCOLORTRIPLE {
byte blue;
byte green;
byte red;
} COLORTRIPLE;
typedef struct tagFILEHEADER {
word ImageFileType;
dword FileSize;
word Reserved1;
word Reserved2;
dword ImageDataOffset;
} FILEHEADER;
typedef struct tagBMPHEADER {
dword HeaderSize;
dword ImageWidth;
dword ImageHeight;
word NumberOfImagePlanes;
word BitsPerPixel;
dword CompressionMethod;
dword SizeOfBitmap;
dword HorizonalResolution;
dword VerticalResolution;
dword NumberOfColorsUsed;
dword
NumberOfSignificantColors;
} BMPHEADER;
typedef struct tagBITMAP {
dword width;
dword height;
COLORTRIPLE *pixel;
FILEHEADER fileheader;
BMPHEADER bmpheader;
} BITMAP;
#define PIXEL(image, row, column) \ image.pixel [(row( * image.width +
(column)]
BITMAP ReadBitmap (FILE *fp);
void WriteBitmap (BITMAP bitmap, FILE *fp);
BITMAP CreateEmptyBitmap
(dword height, dword width);
void ReleaseBitmapData (BITMAP *bitmap);
3. (7 punti) Per pilotare un proiettore a tre LCD è necessario scomporre l’immagine a colori in tre immagini in bianco e nero, ciascuna rappresentante uno dei colori primari, da inviare poi a un pannello a cui è associato un filtro semitrasparente del colore corrispondente.
Si scriva un programma in linguaggio C che riceva sulla riga di comando il nome di un file bitmap, senza estensione. Il
programma deve creare altri tre file bitmap, i cui nomi sono quello del file originale più “_RED”, “_GREEN” e “_BLUE”,
il cui contenuto è l’immagine in bianco e nero della sola componente rossa, verde e blu rispettivamente.
Esempio:
Immagine originale componente RED componente GREEN componente BLUE (ovviamente a colori)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bmp.h"
void CreaComponenti (BITMAP bmp, BITMAP bmp_R, BITMAP bmp_G, BITMAP bmp_B);
int main (int argc, char *argv[]) {
FILE *fpin, *fpoutR, *fpoutG, *fpoutB;
BITMAP bmp, bmp_R, bmp_G, bmp_B;
char filename[64], filenameR[64], filenameG[64], filenameB[64];
if (argc != 2) {
printf ("USO:componenti_RGB <bmp>\n");
exit (EXIT_FAILURE);
}
strcpy (filename, argv[1]);
strcat (filename, ".bmp");
strcpy (filenameR, argv[1]);
strcat (filenameR, "_RED.bmp");
strcpy (filenameG, argv[1]);
strcat (filenameG, "_GREEN.bmp");
strcpy (filenameB, argv[1]);
strcat (filenameB, "_BLUE.bmp");
if ((fpin = fopen (filename, "rb")) == NULL) {
printf ("Error opening input file\n");
exit (EXIT_FAILURE);
}
if ((fpoutR = fopen (filenameR, "wb")) == NULL) {
printf ("Error opening output file\n");
exit (EXIT_FAILURE);
}
if ((fpoutG = fopen (filenameG, "wb")) == NULL) {
printf ("Error opening output file\n");
exit (EXIT_FAILURE);
}
if ((fpoutB = fopen (filenameB, "wb")) == NULL) {
printf ("Error opening output file\n");
exit (EXIT_FAILURE);
}
bmp = ReadBitmap (fpin);
bmp_R = CreateEmptyBitmap (bmp.height, bmp.width);
bmp_G = CreateEmptyBitmap (bmp.height, bmp.width);
bmp_B = CreateEmptyBitmap (bmp.height, bmp.width);
CreaComponenti (bmp, bmp_R, bmp_G, bmp_B);
/* write the files */
WriteBitmap (bmp_R, fpoutR);
WriteBitmap (bmp_G, fpoutG);
WriteBitmap (bmp_B, fpoutB);
ReleaseBitmapData (&bmp);
ReleaseBitmapData (&bmp_R);
ReleaseBitmapData (&bmp_G);
ReleaseBitmapData (&bmp_B);
fclose (fpin);
fclose (fpoutR);
fclose (fpoutG);
fclose (fpoutB);
return EXIT_SUCCESS;
}
void CreaComponenti (BITMAP bmp, BITMAP bmp_R, BITMAP bmp_G, BITMAP bmp_B) {
int row, col;
for (row = 0; row < bmp.height; row++) {
for (col = 0; col < bmp.width; col++) {
PIXEL(bmp_R, row, col).red = PIXEL(bmp_R, row, col).green =
PIXEL(bmp_R, row, col).blue = PIXEL(bmp, row, col).red;
PIXEL(bmp_G, row, col).red = PIXEL(bmp_G, row, col).green =
PIXEL(bmp_G, row, col).blue = PIXEL(bmp, row, col).green;
PIXEL(bmp_B, row, col).red = PIXEL(bmp_B, row, col).green =
PIXEL(bmp_B, row, col).blue = PIXEL(bmp, row, col).blue;
} }
return;
}
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. (6 punti) Si scriva in linguaggio assembler la funzione IN_INTERVALLO che riceve in ingresso tre valori interi nei registri R1, R2 e R3 e restituisce, nel registro R0, il valore uno se R2 ≤ R1 ≤ R3 e zero altrimenti.
IN_INTERVALLO: MV R1 R10 SUB R2 R10 JMPN EXIT_FALSO MV R3 R10 SUB R1 R10 JMPN EXIT_FALSO LDWI R0 1 RET
EXIT_FALSO: LDWI R0 0 RET
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)