Blog ENI : Toute la veille numérique !
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. Le langage assembleur
  3. Notions de base
Extrait - Le langage assembleur Maîtrisez le code des processeurs de la famille X86
Extraits du livre
Le langage assembleur Maîtrisez le code des processeurs de la famille X86 Revenir à la page d'achat du livre

Notions de base

Numération binaire et hexadécimale

1. Le binaire et les données

Ce chapitre est un rappel sur les nombres binaires, base indispensable de l’assembleur. Souvent ignorées par les développeurs haut niveau, il est très important de maîtriser ces théories.

Les ordinateurs et toute l’électronique numérique fonctionnent sur le principe du binaire, autour de l’unité qu’est le BIT, Binary digIT (chiffre binaire), et des données.

Les données sont la raison d’être d’un programme : sans données, un programme ne sert à rien. La lecture d’un flux vidéo, la communication entre deux appareils, les calculs des prévisions météo, l’activation d’un interrupteur... font tous intervenir des données. Les données sont le support de toutes les grandeurs à traiter.

Un bit est l’unité binaire la plus petite, donc la donnée élémentaire.

Un bit peut prendre deux valeurs : 0 ou 1.

Comme un interrupteur qui est soit ouvert soit fermé, une lampe allumée ou éteinte.

01EP01.png

Lorsque la lumière est allumée, on dit que son état est 1, lorsqu’elle est éteinte, on dit que son état est 0. Il ne s’agit ici que d’une convention.

Dans les compatibles PC, l’unité de donnée la plus petite est l’octet (byte en anglais et en assembleur) et est composée de 8 bits.

Un octet étant composé de 8 bits, il peut alors coder une valeur parmi 256 combinaisons possibles.

Un bit ayant deux combinaisons possibles (0 ou 1), 2 bits permettront de coder 4 combinaisons (00, 01, 10, 11), c’est-à-dire 2^2. Et ainsi de suite, selon la formule 2^N, N étant le nombre de bits.

Donc, un octet permet bien de coder 2^8 = 256 combinaisons.

01EP02.png

Cette image représente l’état des bits des 256 solutions d’un octet, une cellule noire correspond à un 0 et une cellule blanche correspond à un 1.

Dans un octet, la suite de bits est ordonnée de sorte que les bits aient un poids.
01EP03.png

Le poids des bits commence à 0.

Le premier bit sera le bit de poids 0, bit de poids faible, LSb (Least Significant bit).

Le dernier sera le bit de poids N-1, bit de poids fort, MSb (Most Significant bit).

L’ordre des bits est utilisé...

Registres, mémoires et variables

1. La donnée et le matériel

a. Le bus

Un bit est transporté sur le circuit par une piste conductrice.

Une donnée de N bits passe par N pistes conductrices, cet ensemble de pistes est appelé BUS.

01EP07.png

Exemple de bus de données 8 bits

Pour permettre une meilleure lecture des schémas de connexions, il est conseillé de représenter un bus de cette manière : un seul trait par groupement de conducteurs, barré par un indicateur affichant le nombre de conducteurs le composant.

01EP08.png

Il y a quatre sortes de bus : le bus de données, le bus d’adresses, le bus de contrôle, et le bus d’alimentation.

Ce dernier n’a pas lieu d’être exploré, sauf dans le cadre d’un développement matériel brut : modding, overclocking ou autre application purement électronique.

b. La mémoire

Un bit mémoire est constitué d’une cellule de type mémoire.

Il existe plusieurs types de cellules mémoire, de la plus rapide à la plus fiable.

Le type de mémoire utilisée pour le travail sur les données en lecture ET en écriture forme la famille des RAM, Random Acces Memory, mémoire à accès aléatoire ou mémoire vive.

La RAM la plus courante, la plus rapide et la moins chère étant un simple condensateur associé à un transistor. Nommée DRAM (RAM Dynamique), cette mémoire est très rapide, mais peu fiable. Son contenu doit être rafraichi à intervalle régulier, il existe un risque d’erreur, corrigé par un circuit ECC (Error Correction Code) intégré ou non aux barrettes de RAM car optionnel.

La mémoire la plus courante pour les registres internes et la RAM intégrée aux CPU est la SRAM (RAM Statique), composée d’une bascule bistable. Cette mémoire peut garder l’information indéfiniment quand le circuit est alimenté, et dans certains cas, peut même garder l’information en l’absence d’alimentation. Mais elle est très lente comparée à la DRAM.

Il existe aussi de la mémoire non volatile, appelée ROM pour Read Only Memory, mémoire à lecture seule ou mémoire morte.

Ce type de mémoire ne peut...

Les diagrammes fonctionnels et les tables

Lors de l’écriture d’un programme, quel que soit le langage de programmation utilisé, il apparaît souvent indispensable de passer par un diagramme fonctionnel.

Le diagramme fonctionnel est la plupart du temps dessiné à main levée sur un papier, de sorte à voir le problème de manière graphique. Mais il est aussi possible de construire un diagramme texte.

En règle générale, l’essentiel est d’arriver à comprendre et à faire comprendre l’idée derrière un diagramme fonctionnel.

Que ce soit pour simplifier, trouver le meilleur algorithme ou communiquer des idées, le diagramme fonctionnel est le tronc commun de tous les langages de programmation.

L’écriture de code se résume à la traduction de chaque case en instruction ou fonction.

De même l’utilisation de tables pour valider des structures de données permet de mieux analyser les actions à effectuer dans certains cas.

Les éléments de base d’un organigramme, outre les symboles de la logique combinatoire, sont :

  • Le rectangle d’ouverture pour indiquer l’entrée d’une routine.

01EPcap1.png
  • Le rectangle pour indiquer une action à effectuer.

01EPcap2.png
  • Le losange pour représenter des choix conditionnels, une sortie oui, et une sortie non.

01EPcap3.png
  • Les maths pour simplifier certaines...

Les mathématiques et l’esprit

Avant même l’apparition des premiers ordinateurs, les mathématiques étaient déjà là pour prédire comment se feraient les traitements à l’intérieur de ces derniers.

Prenons comme exemple Blaise Pascal, qui conçut une machine à calculer mécanique pour son père comptable, la Pascaline, en 1642.

Gottfried Leibniz, qui améliora la Pascaline, inventa le binaire sur la base de théories datant du Premier Empire chinois fondé il y a plus de 4000 ans, et publia un article intitulé Explication de l’arithmétique binaire... en 1673.

Augusta Ada King, comtesse Lovelace, qui dans la première moitié du 19e siècle, a grandement participé, avec Charles Babbage, à élaborer la machine analytique qui est la base des circuits chargés de l’exécution des programmes dans les CPU modernes. Le langage de programmation ADA porte d’ailleurs son nom en hommage.

Georges Boole, qui développa toute la théorie sur la logique combinatoire, basée sur le ET et le OU logique, donnant naissance à l’algèbre de Boole en 1847, aujourd’hui utilisée par les concepteurs de circuits numériques.

Les personnalités ayant contribué à faire avancer la science des ordinateurs sont très nombreuses...

Notions propres à l’assembleur

De par sa nature, l’assembleur fait penser différemment la programmation, il aborde de manière simpliste les traitements complexes, au niveau des actions de base à effectuer, mais devient très vite compliqué en raison du nombre d’opérations élémentaires nécessaires pour traiter des algorithmes.

Au lieu d’effectuer plusieurs calculs en une seule ligne, il effectue un seul calcul en plusieurs lignes.

C’est à ce niveau que l’assembleur déplaît le plus aux programmeurs, car il faut constamment décomposer les actions en instructions élémentaires.

Il existe des exceptions, les nouveaux jeux d’instructions sont conçus pour effectuer des tâches très complexes en une seule instruction, comme par exemple l’instruction POPCNT qui permet de compter le nombre de bits positionnés à 1 dans un opérande.

Mais en dehors de ça, le fait qu’un calcul nécessite plusieurs lignes va permettre de le décomposer et de l’optimiser selon le cas. Ce qui est assez difficile avec un langage de haut niveau. De plus, la décomposition en instructions élémentaires permet de protéger le code de toute analyse car elle permet de disposer les fragments d’une équation dans différentes parties du code, ce qui s’appelle...