Quelques principes de fonctionnement d’un ordinateur (2h) 1 Fonctionnement d’un ordinateur 1.1 Le processeur, cœur de l’ordinateur Tous les ordinateurs manipulent des données binaires 1 codées sous forme électrique : une tension nulle correspond à une valeur 0, une tension non nulle (5V par exemple) à un 1. On sait effectuer des opérations sur ces valeurs. Les principales d’entre elles sont : – opérations unaires : le NON (NOT) – opérations binaires : le ET (AND), le OU (OR) et le OU EXCLUSIF (XOR) À partir de opérateurs basiques, on peut créer des opérations plus compliquées (par exemple un additionneur à 2 bits) À partir de là, on crée un processeur, c’est à dire un circuit électronique capable de réaliser des opérations fondamentales (Unité Arithmétique et Logique) et d’exécuter des programmes (Unité de Contrôle) s’il est couplé à une mémoire : – Opérations logiques (NON, ET, OU, . . . ) (UAL) – Incrémentation, addition (UAL) – Comparaisons (UAL) – Déplacement de valeurs entre différents emplacements de la mémoire (UAL) – Gestion d’une suite d’instructions avec exécution puis avancement d’un pas (UC) – Gestion d’appels et de piles (UC) – Test logiques et branchements conditionnels (UC) 1.2 Les périphériques Deux périphériques sont essentiels au fonctionnement utile d’un ordinateur : la mémoire vive et la mémoire de masse. La mémoire vive est rapide et volatile ; elle permet de stocker l’état actuel de la machine et les données sur lesquelles on est en train de travailler. La mémoire de masse est plus lente mais non volatile, et permet de sauvegarder des données sur un temps long. Pour interagir avec l’extérieur, la carte mère a besoin d’autres périphériques. Ce sont des interfaces entre le processeur et le monde extérieur. Pour permettre le dialogue entre ces entités, on met en place des bus décrits par un protocole standard. Un bus contient 3 fonctions principales : une fonction de contrôle pour synchroniser les échanges ; une fonction d’adressage pour indiquer l’adresse (pixel sur l’écran, fichier sur un DD, . . . ) qu’on lit ou écrit ; et une fonction de lecture ou écriture de données. Les premiers ordinateurs étaient programmés par câblage direct des fils par des opérateurs ! Puis on a progressé : – premier écran cathodique en 1958 (MIT + IBM : Semi Automatic Ground Environnement de l’US Air Force) – utilisation de cartes perforées pour coder les programmes en 1952 (IBM) – premier ordinateur produit en grand volume avec un clavier et un écran de 12 lignes en 1964 (IBM 2260) – invention de la souris en 1968 par D.Engelbart – premier écran tactile lancé par IBM en 1972 – introduction des bandes magnétiques en 1973, puis des lecteurs de disquettes, disques durs. . . 1. Hormis les ordinateurs analogiques, très particuliers et non traités ici. 1 L’utilisation de ces périphériques est intégrée au sein d’un logiciel qui assure la coordination des actions : si on clique ici, ça affiche ça,. . . En gros, un logiciel comporte deux types de tâches : des algorithmes (tâches définies à l’avance, comme un calcul) et des interfaces utilisateurs (réactions à des actions de l’utilisateur). L’interaction se faisant à travers des périphériques de plus en plus développés et donc compliqués, de nombreuses tâches fastidieuses et répétitives apparaissent ; on les code alors une fois pour toute sous forme de librairies. Par exemple, avec l’apparition des écrans, de nouvelles possibilités sont explorées : – Écriture de texte – Tracé de formes géométriques (carrés, lignes, cercles,. . . ) – Affichage d’images – Dessins en 3D – ... Une librairie rassemble des capacités qu’on peut utiliser via un petit ensemble de commandes appelées API (Application Programming Interface). Par exemple une librairie d’écriture de texte à l’écran va spécifier quelle commande utiliser pour écrire un texte, quelle commande pour changer la couleur, . . . Un programme utilise alors uniquement des commandes de librairies pour gérer les fonctions complexes de l’ordinateur. Souvent les librairies utilisent d’autres librairies : on parle alors de couches logicielles (tableau 1) Couche logicielle Programme Librairie GTK Gestionnaire de fenêtres Serveur X11 Noyau Fonction Réalise les actions spécifiques à l’application Gère les objets graphiques (widgets) Gère la position, la taille, la visibilité, . . . des fenêtres Gère l’affichage à l’écran Gère les fonctions de base TABLE 1 – Schéma simplifié des couches logicielles d’une application graphique simple sous Linux Au cours du temps, certaines librairies s’imposent comme des standards ; elle sont alors parfois directement intégrées dans les cartes logiques des ordinateurs. Par exemple, de plus en plus de fonctions graphiques comme la 3D, l’alpha-blending,. . . sont implémentées dans les cartes graphiques. 2 La programmation d’un ordinateur Qu’apporte un langage de programmation ? 2.1 La gestion de la mémoire Un processeur ne connaı̂t que le langage machine sous forme de codes compliqués. Une programmation directe en langage machine est possible grâce à l’assembleur. Il permet d’écrire les instruction machine sous une forme à peu près compréhensible (pour un angliciste). C’est le plus simple des langages de programmation, qui gère l’organisation de la mémoire. On peut lui dire ”réserve moi 2 octets de mémoire sous le nom index”, et il se débrouillera pour le faire. La machine manipule des données sans rien comprendre à ce qu’elle fait. L’assembleur n’en fait pas plus. Les données n’ont pas de type. Par exemple, dans un emplacement de la mémoire se trouvera la chaı̂ne de données 01000101 10001110 ; qu’est-ce que ça veut dire ? Il y a plein de façon de lire ça, tout dépend le sens qu’on y a mis quand on l’a écrit. Un langage de programmation va permettre de gérer les types de données. Dans un langage typé comme C, JAVA, . . . , on déclare une variable en indiquant de quel type elle sera ; dans un langage non typé (ou typé dynamiquement) comme Python, Ruby, Javascript,. . . , la valeur qu’on donne à une variable permet de connaı̂tre son type. Chaque adresse de la mémoire peut contenir des informations. Le déclaration de variables permet de savoir quel type d’information y sera stocké. Un langage de programmation doit aussi permettre de libérer 2 la mémoire quand on n’en a plus besoin, de changer la taille de mémoire utilisée au fur et à mesure du déroulement du programme,. . . En Assembleur, on peut écrire n’importe quoi n’importe où. C’est très rapide, surtout pour tout faire planter. Dans un langage comme le C, on réserve de la mémoire quand on en a besoin, et on peut la libérer (via des commandes allo/realloc/malloc/free). En Python, la mémoire est réservée quand on en a besoin, et un ramasse-miettes (Garbage Collector) se charge de repérer les variables qui ne servent plus et de libérer la mémoire correspondante. C’est pratique pour le programmeur, mais coûteux en performances et amène des problèmes de pertes de mémoires (Memory Leak). 2.2 La gestion des branchements conditionnels et des boucles La gestion des conditions et des boucles est un des points où un langage de programmation amène le plus d’améliorations. Les langages de haut niveau comme Python apportent en plus la notion de boucle sur un tableau (ou tout autre objet itérable) qui facilite l’écriture. Deux exemples suivent pour montrer ce qu’est une boucle et un test en C et Python, et aussi que c’est incompréhensible en assembleur. 2.3 Les paradigmes de programmation Il existe plusieurs façons d’indiquer à un langage de programmation ce qu’on veut faire. La façon la plus naturelle est le paradigme impératif, dans lequel on indique des commande à la suite les unes des autres. Il en existe d’autres, Python en implémente beaucoup, en particulier le paradigme objet qui est très courant. Il s’agit de déclarer des objets avec leurs caractéristiques et ce qu’ils savent faire. L’interpréteur s’occupe alors de faire vivre ces objets. 3 3.1 Systèmes de fichiers Notions générales sur les fichiers Les fichiers sont des espaces dans la mémoire de masse (disque dur,clé USB,. . . ) contenant un certain type d’information. Il a un nom qui est le plus souvent terminé par une extension indiquant le type de contenu du fichier. Il existe deux grandes façons de stocker du contenu dans un fichier : soit en écrivant du texte (fichier texte), soit en écrivant une suite de valeurs, illisible (fichier binaire). La partie sur les droits des fichiers est au programme. . . mais sous windows c’est la foire, tout le monde peut écrire à peu près partout ou presque. Sous Linux c’est plus clair. Paragraphe à reprendre je pense. Les fichiers spéciaux : y en a-t-il d’autres ? Les systèmes de fichiers sont des standards indiquant comment les fichiers vont être stockés sur le disque. Le principal problème est de gérer la modification des fichiers : changement du nom, modification de la taille, ajout de données à la fin, . . . . De manière générale, les fichiers sont tous éparpillés en plusieurs morceaux sur le disque. Chaque système de fichiers a ses avantages et ses inconvénients, le but principal étant : – de garantir une vitesse de lecture/écriture bonne (problème de fragmentation) – d’être robuste : dans certains cas, une erreur de 1bit peut dans certains cas rendre tout le fichier illisible, tandis que dans d’autres cas on peut s’en sortir. 3.2 Organisation générale des fichiers et répertoires Les fichiers sont rangés dans des boı̂tes appelées répertoires (directory en anglais). Un répertoire peut contenir d’autres répertoires. Le répertoire qui contient tous les autres est la racine. Tout répertoire contient par défaut deux répertoires : . qui se représente lui-même, et .. qui représente le répertoire parent (sauf pour la racine). 3 Un fichier est représenté par son chemin absolu : c’est le chemin qui indique comment aller de la racine jusqu’au fichier en passant par différents répertoires. Mais dans de nombreux cas, un fichier a besoin d’en appeler un autre situé tout près, sans remonter à la racine. Le chemin relatif est alors très utile. En particulier, si (dans l’exemple montré) on déplace rep1 à un autre emplacement, le chemin absolu change, mais le chemin relatif reste. Les différents disques peuvent correspondre à diverses racines : c’est le choix du système Windows. Les autres systèmes de type Unix choisissent un disque comme racine, et les autres disques sont montés comme des répertoires. Attention à la convention typographique : les répertoires sont toujours séparés par des slash / (sous Unix, ou dans les URL des navigateurs internet) sauf sous Windows où c’est un backslash \. FTP : que faut-il en dire ? 3.3 Encodage des fichiers Rien à ajouter, ça parle tout seul. On rencontrera surtout ces problèmes avec les lectures/écritures de fichiers (pour les BDD à la fin de l’année, un peu aussi pour la sauvegarde de tableaux Numpy). 4