--- layout: default title: Esercitazione del 3 maggio 2019 ---
uniroma1
.*_main.c
.cognome.nome
. Sulle postazioni del laboratorio sarà /home/biar/Desktop/cognome.nome/
.cognome.nome.zip
(zip -r cognome.nome.zip cognome.nome/
).cognome.nome.zip
.E2-file-copy/file1.dat
e E2-file-copy/file2.dat
per ridurre la quantitità di byte da trasferire su Google Formsrm -rf cognome.nome
).Per maggiori informazioni fate riferimento al regolamento delle esercitazioni.
Tradurre in IA32 la seguente funzione list_equal_array
definita in E1-list-array-equal/e1.c
che, dato in p
il puntatore al primo nodo di una lista di short
e un array di n
short, restituisce 1 se la lista è uguale all’array e 0 altrimenti.
e1.c
#include "e1.h"
#include <stdlib.h>
int list_equal_array(const node_t *p, short *buf, int n) {
int i;
for (i = 0; i < n; i++) {
if (p == NULL || p->elem != buf[i]) return 0;
p = p->next;
}
return p == NULL;
}
Si riporta un estratto del file e1.h
che definisce il tipo node_t
:
typedef struct node_t {
short elem;
struct node_t *next;
} node_t;
Scrivere la soluzione nel file E1-list-array-equal/e1.s
. Usare il file E1-list-array-equal/e1_eq.c
per sviluppare la versione C equivalente.
Scrivere nel file T2-file-copy/e2.c
una funzione int copy(const char* src, const char* dst)
che realizza la copia di un file di dimensione arbitraria con nome file sorgente src
e destinazione dst
. La funzione deve restituire EXIT_FAILURE
in caso di errore e EXIT_SUCCESS
altrimenti.
Suggerimento: allocare dinamicamente un buffer da usare per il travaso di dati dal file sorgente al file destinazione. Provare con dimensioni diverse scegliendo la minima ragionevole per mantenere le prestazioni.
Usare il programma di prova ./test.sh
che compila, esegue e verifica il risultato.
Domanda 1 Con riferimento ai permessi sui file, la notazione ottale 0640 a quale configurazione di permessi corrisponde?
-wx--x---
rw-r-----
r-xr-----
---rw-r--
rw-r--r--
rwxrw-r--
Domanda 2 Dato il seguente codice, quale tra le seguenti affermazioni è corretta?
test.txt
viene aperto in sola scritturatest.txt
esiste già, la open
restituisce -1
test.txt
viene creato con i permessi di lettura e scrittura per “user”, “group” e “others”test.txt
contiene esclusivamente i caratteri hello
write
fallisce sempre perché non è possibile scrivere sul file a causa di come viene creato dalla open
Domanda 3 Quale tra le seguenti affermazioni è FALSA?
/proc/<pid>
, dove <pid>
è un numero intero, contiene informazioni sul processo con PID=<pid>
Domanda 4 Data la seguente porzione di codice, selezionare la risposta corretta:
s
è una variabile puntatore che punta ad un array di char
allocato nella sezione “data” del processos
è una variabile puntatore che punta ad un array di char
allocato nello stack frame della funzione main
s
è un array di char
allocato nella sezione “data” del processos
è un array di char
allocato nello stack frame della funzione main
Domanda 5 Data la seguente porzione di codice, selezionare la risposta corretta:
s
è una variabile puntatore che punta ad un array di char
allocato nella sezione “data” del processos
è una variabile puntatore che punta ad un array di char
allocato nello stack frame della funzione main
s
è un array di char
allocato nella sezione “data” del processos
è un array di char
allocato nello stack frame della funzione main
Domanda 6 Supponendo di essere su una architettura con indirizzi di 32 bit, se la dimensione di una pagina di memoria è 4 kB (4096 byte), lo spazio di indirizzamento logico di un processo quante pagine (allocate o meno) contiene? (con la notazione 2^n si indica 2 elevato al numero n)
Domanda 7 Sia A = 0x08F444D8
un indirizzo nello spazio di indirizzamento logico di un processo P, su un’architettura a 32 bit.
Si assuma che la memoria virtuale utilizzi pagine di 4 kB (4096 byte). Indicare il numero di pagina e l’offset di A
(in decimale):
Domanda 8 Sia A = 0xFF9257B0
un indirizzo nello spazio di indirizzamento logico di un processo P, su un’architettura a 32 bit.
Si assuma che la memoria virtuale utilizzi pagine di 4 kB (4096 byte) e che la pagina dell’indirizzo A
sia stata mappata nel frame numero 128 (decimale). Indicare l’indirizzo fisico corrispondente all’indirizzo logico A
:
0xFF925128
0xFF925080
0xFF1287B0
0x008057B0
0x000807B0
0x809257B0
e1_eq.c
#include "../e1.h"
#include <stdlib.h>
int list_equal_array(const node_t *p, short *buf, int n) {
const node_t *edx = p;
short *ebx = buf;
int edi = n;
// Registers; i<->ecx, p<->edx, tmp<->eax, buf <-> ebx, n <->edi
int ecx=0;
L: if (ecx >= edi) goto E;
if (edx == NULL) goto F;
int eax = edx->elem;
if (eax != ebx[ecx]) goto F;
edx = edx->next;
ecx++;
goto L;
E: return edx == NULL;
F: return 0;
}
e1.s
.globl list_equal_array
# typedef struct node_t { // base
# short elem; // offset: 0 |xx..| (base)
# struct node_t *next; // offset: 4 |xxxx| 4(base)
# } node_t; // sizeof: 8
list_equal_array: # int list_equal_array(const node_t *p, short *buf, int n) {
pushl %ebx
pushl %edi
movl 12(%esp), %edx # const node_t *edx = p;
movl 16(%esp), %ebx # short *ebx = buf;
movl 20(%esp), %edi # int edi = n;
# Registers: i<->ecx, p<->edx, tmp<->eax, buf <-> ebx, n <->edi
xorl %ecx, %ecx # int ecx = 0;
L: cmpl %edi, %ecx # if (ecx >= edi)
jge E # goto E;
testl %edx, %edx # if (edx == NULL)
je E # goto F
movw (%edx), %ax # int eax = edx->elem;
cmpw (%ebx, %ecx, 2), %ax # if (eax != ebx[ecx])
jne F # goto F;
movl 4(%edx), %edx # edx = edx->next;
incl %ecx # ecx++;
jmp L # goto L;
E: testl %edx, %edx # return edx == NULL;
sete %al
movsbl %al, %eax
jmp G
F: xorl %eax, %eax # return 0
G: popl %edi
popl %ebx
ret
e2.c
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "e2.h"
void check_perror(int res, const char* msg);
#define BUF_SIZE 8192
int copy(const char* src, const char* dst) {
int res;
void* buf;
// allocazione buffer
buf = malloc(BUF_SIZE);
if (buf == NULL) {
fprintf(stderr, "malloc");
exit(EXIT_FAILURE);
}
// open files
int fdin = open(src, O_RDONLY);
check_perror(fdin, "open");
int fdout = open(dst, O_WRONLY | O_CREAT | O_TRUNC, 0644);
check_perror(fdout, "open");
// copy loop
while(1) {
ssize_t r = read(fdin, buf, BUF_SIZE);
check_perror(r, "read");
if (r==0) break;
ssize_t w = write(fdout, buf, r);
check_perror(w, "write");
}
// close files
res = close(fdin);
check_perror(res, "close");
res = close(fdout);
check_perror(res, "close");
// allocazione buffer
free(buf);
return EXIT_SUCCESS;
}
void check_perror(int res, const char* msg) {
if (res != -1) return;
perror(msg);
exit(EXIT_FAILURE);
}
rw-r-----
test.txt contiene esclusivamente i caratteri
hello``