1 / 45

Laboratorio di Programmazione di Sistema - Corsi Riuniti

Susanna Pelagatti, Stefano Chessa, Augusto Ciuffoetti Edoardo Pistoletti, Stefano Cataudella, Claudio Scordino susanna@di.unipi.it Ricevimento: Gio 11.00-12.30 e 14.00-15.30 Oppure per posta elettronica http://www.di.unipi.it/~susanna/LPS/.

zeal
Download Presentation

Laboratorio di Programmazione di Sistema - Corsi Riuniti

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Susanna Pelagatti, Stefano Chessa, Augusto Ciuffoetti Edoardo Pistoletti, Stefano Cataudella, Claudio Scordino susanna@di.unipi.it Ricevimento: Gio 11.00-12.30 e 14.00-15.30 Oppure per posta elettronica http://www.di.unipi.it/~susanna/LPS/ Laboratorio di Programmazione di Sistema - Corsi Riuniti

  2. Struttura del corso • Lezioni in aula (A) + esercitazioni (aule H, M) • gli studenti sono divisi in 4 gruppi • A1, A2, B1, B2 • la lezione del Lunedì (14-16) è per tutti gli studenti • le esercitazioni del Mercoledì sono per gruppi • 9-11 (Aula M -- Chessa) per il gruppo A1 • 11-13 (Aula M -- Ciuffoletti) per il gruppo A2 • 11-13 (Aula H -- Pelagatti) per il gruppo B1 • 14-16 (Aula H -- Pelagatti) per il gruppo B2

  3. Struttura del corso (2) • Per partecipare alle esercitazioni è necessario iscriversi nella lista • LPS è un corso senza obbligo di frequenza • E’ però fortemente consigliata!

  4. Struttura del corso (3) • Esame • Non ci sono compitini ma solo il progetto finale • Si svolge in gruppi di 2/3 persone • Il progetto è più impegnativo di quelli dei laboratori precedenti (6 crediti invece di 4: 2 crediti di lavoro autonomo per lo svolgimento del progetto) • C’è una discussione individuale del progetto • Stabilire il grado di partecipazione alla stesura • Stabilire il voto finale (individuale)

  5. Programma di massima • Introduzione al linguaggio C (18h) • Interazione con la shell (2h) • Programmazione di sistema in Unix (20h)

  6. Libri di Testo • Testi di riferimento per C e Unix • Glass, Ables, Unix for programmers and users, Prentice Hall 1999 • Kelley, Pohl C: Didattica e programmazione (2ed), Addison Wesley 2004 • Testo di esempi ed esercizi • Gervasi, Pelagatti, Ruggieri, Scozzari, Sperduti Programmazione di Sistema in Linguaggio C SEU

  7. Il linguaggio C

  8. Perché il linguaggio C? • Larga diffusione nel software applicativo • Standard di fatto per lo sviluppo di software di sistema • Visione a basso livello della memoria • Capacità di manipolare singoli bit

  9. Perché il linguaggio C? (2) • Standard di fatto per lo sviluppo di software di sistema (cont.) • possibilità di incapsulare parti di codice assembler che effettuano compiti impossibili da esprimere in linguaggi ad alto livello • es. esecuzione di istruzioni ‘speciali’ (TRAP), manipolazione diretta di registri • Compilazione estremamente efficiente • Occupazione di memoria ridotta

  10. C : caratteristiche fondamentali • Paradigma imperativo • costrutti di controllo simili a Java (while-do, for, if (..) else, switch) • tipi base molto simili a Java (int, double etc…) • Ma … NON è un linguaggio ad oggetti • NON supporta la nozione di oggetti, classi o meccanismi di ereditarietà • la principale forma di strutturazione sono le funzioni • un programma C è una collezione di funzioni di cui una di nome main • le funzioni possono risiedere in uno o più file

  11. C : caratteristiche fondamentali (2) • Memoria e puntatori • in C è possibile conoscere e denotare l’indirizzo della cella di memoria in cui è memorizzata una variabile (il puntatore) • es : int a = 50; /* una var intera */ int * b; /* una var puntatore a interi */ ... b = &a; /* assegna a b l’indirizzo della cella in cui è memorizzata a */

  12. C : caratteristiche fondamentali (3) • Memoria e puntatori • in C è possibile conoscere e denotare l’indirizzo della cella di memoria in cui è memorizzata una variabile (il puntatore) • es : int a = 50; int *b; … b = &a; a è memorizzata nella cella 350 50 350 ... 450

  13. C : caratteristiche fondamentali (4) • Memoria e puntatori • in C è possibile conoscere e denotare l’indirizzo della cella di memoria in cui è memorizzata una variabile (il puntatore) • es : int a = 50; int *b; … b = &a; 50 350 ... 450 b è memorizzata nella cella 450

  14. C : caratteristiche fondamentali (5) • Memoria e puntatori • in C è possibile conoscere e denotare l’indirizzo della cella di memoria in cui è memorizzata una variabile (il puntatore) • es : int a = 50; int *b; … b = &a; 50 350 350 450 Dopo questo assegnamento in b è memorizzato l’indirizzo di a

  15. C : caratteristiche fondamentali (6) • Memoria e puntatori • è possibile conoscere e/o modificare il contenuto di una variabile manipolando direttemente il suo puntatore (operatore di dereferenziazione ‘ * ’) • es : int a = 50; int *b = &a; … *b = *b + 4; 54 350 350 450 Dopo questo assegnamento in a è memorizzato il valore 50 + 4

  16. C : un primo programma • Il più semplice programma C è costituito da • una singola funzione (main) • memorizzata in un singolo file

  17. C : un primo programma (2) • /* Programma che calcola il massimo fra tre numeri inseriti da tastiera */ • #include <stdio.h> • #define N 4 • int main (void){ • int i, tmp, max=0; • printf(“Inserisci %d interi positivi\n”,N); • for (i = 0; i < N; i++) { • scanf(“ %d”, &tmp); • max = (max > tmp)? max : tmp ; • } • printf(“Il massimo è %d \n”,max); • return 0; • }

  18. C : un primo programma (3) • /* Programma che calcola il massimo fra tre numeri inseriti da tastiera */ • #include <stdio.h> • #define N 4 • int main (void){ • int i, tmp, max=0; • printf(“Inserisci %d interi positivi\n”,N); • for (i = 0; i < N; i++) { • scanf(“ %d”, &tmp); • max = (max > tmp)? max : tmp ; • } • printf(“Il massimo è %d \n”,max); • return 0; • } Commenti

  19. Commenti • I commenti possono essere inseriti con • /* qua un commento anche su più linee */ • // commento su singola linea

  20. C : un primo programma (4) Inclusione delle informazioni necessarie per utilizzare le funzioni nelle librerie standard di I/O del C • #include <stdio.h> • #define N 3 • int main (void){ • int i, tmp, max=0; • printf(“Inserisci %d interi positivi\n”,N); • for (i = 0; i < N; i++) { • scanf(“ %d”, &tmp); • max = (max > tmp)? max : tmp ; • } • printf(“Il massimo è %d \n”,max); • return 0; • }

  21. C : un primo programma (5) Inclusione delle informazioni necessarie per utilizzare le funzioni nelle librerie standard di I/O del C • #include <stdio.h> • #define N 3 • int main (void){ • int i, tmp, max=0; • printf(“Inserisci %d interi positivi\n”,N); • for (i = 0; i < N; i++) { • scanf(“ %d”, &tmp); • max = (max > tmp)? max : tmp ; • } • printf(“Il massimo è %d \n”,max); • return 0; • } Funzioni per leggere da tastiera, visualizzare dati

  22. C : un primo programma (6) Definizione di MACRO (costante simbolica) • #include <stdio.h> • #define N 3 • int main (void){ • int i, tmp, max=0; • printf(“Inserisci %d interi positivi\n”,N); • for (i = 0; i < N; i++) { • scanf(“%d”, &tmp); • max = (max > tmp)? max : tmp ; • } • printf(“Il massimo è %d \n”,max); • return 0; • } - N è il nome simbolico per la sequenza di caratteri “3” - Ogni occorrenza di N viene sostituita da “3” prima di iniziare la compilazione

  23. C : un primo programma (7) Intestazione della funzione, fornisce : - il tipo del valore prodotto dalla funzione (int) - descrizione degli argomenti (in questo caso nessuno (void)) • #include <stdio.h> • #define N 3 • int main (void){ • int i, tmp, max=0; • printf(“Inserisci %d interi positivi\n”,N); • for (i = 0; i < N; i++) { • scanf(“%d”, &tmp); • max = (max > tmp)? max : tmp ; • } • printf(“Il massimo è %d \n”,max); • return 0; • }

  24. C : un primo programma (8) Dichiarazione di variabili locali alla funzione (il loro spazio di memoria viene allocato all’inizio della esecuzione della funzione e deallocato alla fine) • #include <stdio.h> • #define N 3 • int main (void){ • int i, tmp, max=0; • printf(“Inserisci %d interi positivi\n”,N); • for (i = 0; i < N; i++) { • scanf(“%d”, &tmp); • max = (max > tmp)? max : tmp ; • } • printf(“Il massimo è %d \n”,max); • return 0; • }

  25. C : un primo programma (9) Invocazione della funzione di libreria che scrive su video • #include <stdio.h> • #define N 3 • int main (void){ • int i, tmp, max=0; • printf(“Inserisci %d interi positivi\n”,N); • for (i = 0; i < N; i++) { • scanf(“%d”, &tmp); • max = (max > tmp)? max : tmp ; • } • printf(“Il massimo è %d \n”,max); • return 0; • }

  26. C : un primo programma (10) Stringa di formattazione Placeholder (segnaposto) per un valore intero (%d) • #include <stdio.h> • #define N 3 • int main (void){ • int i, tmp, max=0; • printf(“Inserisci %d interi positivi\n”,N); • for (i = 0; i < N; i++) { • scanf(“%d”, &tmp); • max = (max > tmp)? max : tmp ; • } • printf(“Il massimo è %d \n”,max); • return 0; • }

  27. C : un primo programma (11) Il segnaposto viene rimpiazzato con il valore dei parametri (in ordine) • #include <stdio.h> • #define N 3 • int main (void){ • int i, tmp, max=0; • printf(“Inserisci %d interi positivi\n”,N); • for (i = 0; i < N; i++) { • scanf(“%d”, &tmp); • max = (max > tmp)? max : tmp ; • } • printf(“Il massimo è %d \n”,max); • return 0; • }

  28. C : un primo programma (12) • #include <stdio.h> • #define N 3 • int main (void){ • int i, tmp, max=0; • printf(“Inserisci %d interi positivi\n”,N); • for (i = 0; i < N; i++) { • scanf(“%d”, &tmp); • max = (max > tmp)? max : tmp ; • } • printf(“Il massimo è %d \n”,max); • return 0; • } Invocazione della funzione di libreria che legge da tastiera

  29. C : un primo programma (13) Indirizzo (&) della variabile (tmp) in cui deve essere inserito il valore intero (%d) letto da tastiera. • #include <stdio.h> • #define N 3 • int main (void){ • int i, tmp, max=0; • printf(“Inserisci %d interi positivi\n”,N); • for (i = 0; i < N; i++) { • scanf(“%d”, &tmp); • max = (max > tmp)? max : tmp ; • } • printf(“Il massimo è %d \n”,max); • return 0; • }

  30. C : un primo programma (14) Espressione condizionale • #include <stdio.h> • #define N 3 • int main (void){ • int i, tmp, max=0; • printf(“Inserisci %d interi positivi\n”,N); • for (i = 0; i < N; i++) { • scanf(“%d”, &tmp); • max = (max > tmp)? max : tmp ; • } • printf(“Il massimo è %d \n”,max); • return 0; • }

  31. C : un primo programma (15) Comando return : termina l’esecuzione della funzione e restituisce il valore delle espressione specificata • #include <stdio.h> • #define N 3 • int main (void){ • int i, tmp, max=0; • printf(“Inserisci %d interi positivi\n”,N); • for (i = 0; i < N; i++) { • scanf(“%d”, &tmp); • max = (max > tmp)? max : tmp ; • } • printf(“Il massimo è %d \n”,max); • return 0; • } Per convenzione se tutto è andato bene il main restituisce 0.

  32. Come si esegue un programma C? • Prima di essere eseguito dal processore il programma deve essere • 1. pre-processato • 2. compilato • 3. collegato (linking) • 4. caricato in memoria (loading) • Vediamo come funzionano le fasi 1,2,4 • il linking verrà discusso più avanti

  33. Pre-processing e compilazione • Il programma deve essere editato e salvato in un file con estensione ‘.c’ • es. posso salvare il programma esempio nel file prova.c • Non c’è alcun rapporto fra il nome del file ed il nome delle funzioni in esso contenute (!= Java)

  34. Pre-processing e compilazione (2) • Il compilatore può essere invocato con il comando gcc -Wall -pedantic -g prova.c -o nomees • -Wall -pedantic opzioni che aumentano il numero di controlli e di messaggi di ‘avvertimento’ visualizzati • -g opzione che include anche le informazioni necessarie al debugger • prova.c nome del file da compilare/preprocessare • -o nomees opzione che permette di decidere il nome del file eseguibile (nomees). Altrimenti il file eseguibile si chiama di default a.out

  35. Pre-processing e compilazione (3) • Preprocessing • #include <file> • #include “file” queste linee vengono rimpiazzate dal contenuto dei file specificati (<file> viene cercato tra gli header standard, su Linux /usr/include; “file” viene cercato a partire dalla directory corrente) • #define nome testo • rimpiazza ogni occorrenza di nome con il testo specificato • è possibile specificare del testo parametrico

  36. Pre-processing e compilazione (4) • Compilazione • trasforma il file preprocessato (senza più #include o #define) in un file eseguibile che contiene • alcune informazioni di carattere generale • rappresentazione binaria di (parte dei) dati del programma (variabili globali) • codice assembler eseguibile dal processore target (testo) • per capire come avviene questa traduzione, dobbiamo specificare come un programma vede la memoria durante la sua esecuzione (spazio di indirizzamento) • un programma in esecuzione viene comunemente detto processo

  37. Spazio di indirizzamento Pila di FRAME, uno per ogni chiamata di funzione da cui non abbiamo ancora fatto ritorno 232 - 1 Stack Area vuota Variabili globali a tutte le funzioni Data Traduzione in assembler delle funzioni che compongono il programma Text 0

  38. Spazio di indirizzamento (2) 232 - 1 Stack Direzione di crescita dello stack Area vuota Contenuti tipici di un FRAME : - variabili locali della funzione - indirizzo di ritorno (indirizzo dell’istruzione successiva a quella che ha effettuato la chiamata alla funzione) - copia dei parametri di chiamata Data Text 0

  39. Spazio di indirizzamento (3) All’inizio dell’esecuzione lo Stack contiene solo il FRAME per la funzione main Successivamente : * ogni volta che viene chiamata una nuova funzione viene inserito un nuovo frame nello stack * ogni volta che una funzione termina (es. return 0) viene eliminato il frame in cima dello stack e l’esecuzione viene continuata a partire dall’indirizzodi ritorno • Spazio di indirizzamento 232 - 1 Stack Area vuota Data Text 0

  40. Spazio di indirizzamento (4) 232 - 1 Stack Area vuota Direzione di crescita dello heap heap Data Spazio di memoria dedicato ai dati globali a tutte le funzioni. Diviso in statico per i dati la cui dimensione è nota a tempo di compilazione e dinamico (heap) Text 0

  41. Compilazione : un esempio Ogni variabile corrisponde ad una o più parole/celle di memoria • int main (void){ • int i, tmp, max=0; • printf(“Inserisci %d interi positivi\n”,N); • for (i = 0; i < N; i++) { • scanf(“%d”, &tmp); • max = (max < tmp)? max : tmp ; • } • printf(“Il massimo è %d \n”,max); • return 0; • } 32 bit &i &max &tmp

  42. Compilazione : un esempio (2) Ogni statement viene tradotto in - istruzioni assembler che lavorano sulle celle rilevanti - CALL di altre funzioni (es. printf) • int main (void){ • int i, tmp, max=0; • printf(“Inserisci %d interi positivi\n”,N); • for (i = 0; i < N; i++) { • scanf(“%d”, &tmp); • max = (max < tmp)? max : tmp ; • } • printf(“Il massimo è %d \n”,max); • return 0; • } &i &max &tmp

  43. Formato del file eseguibile • La compilazione produce un file eseguibile (es. a.out) • Il formato di un eseguibile dipende dal sistema operativo • In Linux un eseguibile ha il formato ELF (Executable and Linking Format)

  44. Formato del file eseguibile (2) • Formato di un eseguibile ELF Numero che contraddistingue il file come eseguibile File a.out Magic number Ampiezza area di memoria occupata dalle variabili globali NON inizializzate Altre info Ampiezza BSS Variabili globali inizializzate I-Data segment Text segment Codice del programma (assemblato)

  45. Formato del file eseguibile (3) FRAME per la funzione main • L’eseguibile contiene tutte le informazioni per creare la configurazione iniziale dello spazio di indirizzamento (loading) File a.out 232 - 1 Stack Area vuota Magic number Altre info BSS-segment Data Ampiezza BSS I-Data segment I-Data segment Text segment Text 0

More Related