Les différences entre les systèmes


Nous pourrions nous poser la question de savoir pourquoi il y a autant de différences entre les processeurs, l'évolution de ces derniers étant un facteur important, mais nous nous attarderons principalement à énumérer ces différences, et à identifier les systèmes qui ont une configuration particulière.

Taille des mots

Tout d'abord, lorsque l'on souhaite télécharger et installer un logiciel sur notre ordinateur aujourd'hui, il faut généralement choisir entre la version 32 bits et la version 64 bits. Cette version correspond en fait à la taille des mots que notre processeur est capable de traiter. L'architecture historique(si l'on peut qualifier d'histoire une trentaine d'années.) est 32 bits, c'est-à-dire que la taille des adresses en mémoire et des registres est de 32 bits. Cette taille correspond également à la taille d'un int lorsque l'on codera en C. Le fait d'avoir une adresse limitée à 32 bits ne permet d'adresser que 4 Gio de mémoire vive. En passant à un processeur 64 bits, on peut alors adresser jusqu'à 16 Eio.

En théorie, un programme compilé sur une machine 32 bits et exécuté sur une machine 64 bits devrait fonctionner tout à fait normalement, car le processeur est capable de passer en mode 32 bits, alors qu'évidement l'inverse n'est pas vraie. Cependant, des exceptions existent et il est préférable d'avoir une version du programme compilée pour la bonne architecture.

Endianness

L'endianness peut devenir un problème lorsque l'on souhaite exporter un programme vers une architecture spécifique. La plupart du temps, l'endianness est le même sur les processeurs classiques (x86). Il définit l'ordre dans lequel un mot de plusieurs octets est stocké en mémoire. Les deux principaux endianness existant sont le big endian et le little endian.

Little endian

En little endian, c'est l'octet de poids le plus faible qui est stocké en premier, donc pour ce mot de 4 octets : 0x4D78AC20, le tableau représentant la mémoire sera le suivant :

Adresses 0 1 2 3
Données 20 AC 78 4D

Big endian

En big endian, le stockage est effectué avec l'octet de poids fort en premier. En reprenant l'exemple précédent, la représentation de la mémoire serait la suivante :

Adresses 0 1 2 3
Données 4D 78 AC 20

Les processeurs et l'endianness

L'endianness tend à ne plus être problématique, car certains processeurs, comme les ARM ou les intel x86_64 sont capables de fonctionner suivants les deux modes, il faut tout de mêmes le préciser soit au niveau logiciel, soit au niveau matériel. Il faut tout de même se poser la question lorsque par exemple on souhaite exporter un programme compilé sur un processeur x86 (little endian) vers une station SPARC (big endian).

Alignement mémoire

Certains processeurs ne sont capables de lire des mots complets de 32 bits uniquement sur des adresses multiples de 4. C'est le cas des processeurs ARM, qui ne sont pas capables de lire un int à l'adresse 2 :

Adresses 4 5 6 7
Données AC 20 -- --
Adresses 0 1 2 3
Données -- -- 4D 78

Par contre, le processeur est capable de lire un int s'il commence à l'adresse 4 :

Adresses 4 5 6 7
Données 4D 78 AC 20
Adresses 0 1 2 3
Données -- -- -- --

L'alignement est donc à prendre en compte lors de la compilation du programme. Si l'on utilise GCC, certaines optimisations peuvent être appliquées pour aligner les données. On peut également tenter de le spécifier dans le programme ( en C) grâce à l'instruction suivante :

			
			
			
	int x __attribute__((aligned(4))) = 42;
				

Cependant, cela demande la réécriture des programmes, alors que GCC contient des options pour la plupart des machines cibles ayant des contraintes d'alignements.

Types signés

Le fait que les types primitifs soient signés ou non pose des problèmes assez conséquents. Un char n'a pas la même valeur si il est signé ou si il ne l'est pas. Par exemple :

			
			
	unsigned char c1 = 0xFA // donne 250
	signed char c2 = 0xFA // donne -6
				

Jeux d'instructions

Le jeu d'instructions d'un processeur rassemble toutes les commandes qu'il est capable d'exécuter. Ces instructions sont inhérentes au processeur et peuvent changer selon le fabricant. Évidemment, la plupart des fabricants utilisent un jeu d'instruction standard rassemblant les mêmes fonctionnalités et étant codé de la même manière. Ils peuvent néanmoins ajouter des instructions supplémentaires, et lorsqu'un programme utilise ces ajouts, il n'est plus portable vers un système différent.

Les librairies systèmes

Le dernier point problématique lors de l'export d'un programme compilé est évidemment le système d'exploitation qui recevra le programme. Si les deux systèmes sont différents, il est clair que l'export ne fonctionnera pas, car les bibliothèques systèmes pour faire des appels au noyau ne sont pas les mêmes.

Sous Linux, la librairie système la plus répandue est évidemment la libC. Même s'il existe des alternatives telle que µclibC, le fonctionnement reste le même, le support des divers jeux d'instructions des processeurs est effectué par le noyau, la librairie fait simplement le lien entre le noyau et le programme.

Pour Windows, il est difficile de savoir comment les liens sont effectués, on peut seulement connaitre le nom de la bibliothèque C qui est : MSVCRT.DLL