Comment les ordinateurs savent-ils quoi faire avec « 1 » et « 0 » ? Chaque fois que j’essaie de le découvrir, c’est juste des gens qui expliquent le binaire, sans jamais dire comment un ordinateur sait, par exemple, prendre ‘0110’ et en faire ‘6’.


Il n'est pas clair quelle est votre question, mais je vais essayer d'y répondre de plusieurs façons. Je vais rester simple au début et en dessous de la ligne de tirets, je la rendrai plus pédamment correcte.

1) Pourquoi les gens vous expliquent-ils le binaire, quand vous posez la question ? Ils vous expliquent le binaire parce qu'à l'intérieur de l'ordinateur il y a des circuits qui font de l'arithmétique de complément à 2s. L'arithmétique de complément à 2 est "binaire". L'ordinateur possède des circuits qui savent comment faire de l'arithmétique binaire. Lorsque le programmeur demande à l'ordinateur d'effectuer une addition, l'ordinateur utilise le circuit qui effectue l'addition en complément à 2 (c'est-à-dire en binaire). En binaire complémentaire à 2, la chaîne de bits 0110 est égale à 6 en arithmétique décimale. Ainsi, lorsque l'ordinateur calcule, il fait de l'arithmétique binaire. Voir sous la ligne pour d'autres façons dont l'ordinateur peut calculer.


2) Ok, supposons maintenant que nous avons 0110 stocké quelque part dans l'ordinateur et que nous voulons l'afficher sur l'écran. Comment l'ordinateur fait-il cela ? C'est beaucoup plus compliqué. Tellement, compliqué que même si je connais tous les principes de son fonctionnement et que j'ai effectivement conçu des ordinateurs et des puces informatiques et de grands logiciels complexes, je ne connais pas tous les détails pertinents pour votre ordinateur spécifique, donc je ne peux l'expliquer que de manière générale. Commençons donc par ce que le programmeur écrit. Voici un programme ressemblant vaguement à du C, dépouillé de détails non pertinents, mais conçu pour illustrer votre question. This is called pseudocode by the way.

  1. main () { 
  2. binary integer b = 0110; // b has 0110 in it now 
  3. printf("%d", b); // print those bits as a decimal number 

Donc, dans ce programme, le programmeur a dit à l'ordinateur de stocker le bit 0110 quelque part dans sa mémoire et d'appeler cet endroit "b". La ligne suivante dit à l'ordinateur que nous voulons imprimer sur l'écran n'importe quel bit qui se trouve dans l'emplacement appelé "b" mais en les traduisant en un nombre décimal.

Maintenant, ce qui est important à ce sujet. Le programmeur a dit à l'ordinateur de "comprendre" les bits comme un nombre décimal. Le programmeur aurait pu utiliser une déclaration différente pour que l'ordinateur les restitue simplement sous forme de points sur l'écran. Ou peut-être comme une lettre de l'alphabet (quelle est la 6ème lettre de l'alphabet, c'est "f" en anglais - bien que les ordinateurs ne connaissent pas l'anglais en soi. See below the line for the alphabets the computer does know.

  1. main () { 
  2. binary integer b = 0110; // b has 0110 in it now 
  3. gui.printsprite(b, 0, 5); // print those bits as dots on the screen 

Ce programme imprimerait plutôt quelque chose comme:

Sauf que les points rempliraient les espaces qu'ils occupent (et sembleraient se toucher). Les points d'addition (appelés pixels) sont généralement assez petits. Voir sous la ligne pour plus d'infos à ce sujet.

3) Ok, maintenant nous savons que l'ordinateur ne sait pas ce qu'est 0110 jusqu'à ce que le programmeur lui dise comment l'interpréter. Et le programmeur utilise un langage de programmation pour le faire. Et, ensuite, nous allons découvrir que l'ordinateur ne comprend pas du tout les langages de programmation. L'ordinateur ne comprend que son propre langage appelé "code machine". Le type d'ordinateur détermine le langage de code machine qu'il comprend. Votre PC comprendra le code machine x86. Votre téléphone (qui est en fait un ordinateur) comprendra le code machine ARM. Les gros serveurs des banques comprennent généralement le code machine 370. Devinez quoi ? plus sur le dessous de la ligne.

Et le code machine est juste des modèles de bits comme où 0110 0011 1011 0110 0000 0010 a une signification spécifique aux ordinateurs de la même famille (qui comprennent le même code machine). Je n'ai aucune idée de la signification de cette séquence de bits, mais je pourrais la rechercher (ou demander à quelqu'un comme Joe Zbiciak, qui traite du code machine plus fréquemment que moi) ce qu'elle signifie sur un processeur spécifique. Notez que le 0110 dans le motif ne signifie probablement pas 6.

Mais de toute façon, nous devons faire traduire notre programme dans la séquence appropriée de motifs de bits. De sorte que nous avons dit à l'ordinateur que nous voulons qu'un 6 soit imprimé sur l'écran (ou les points ou la lettre f etc). C'est là que j'interviens. J'écris des programmes spécialisés appelés compilateurs. Ce sont des programmes qui font "comprendre" les langages de programmation et quelles séquences de bits font faire diverses choses à l'ordinateur et qui peuvent traduire le langage de programmation dans le bon ensemble de bits, afin que l'ordinateur comprenne ce que nous voulons qu'il fasse.

4) Parlons maintenant un peu de la façon dont l'ordinateur fait cela. L'ordinateur est en quelque sorte une horloge mécanique géante, comme les tours d'horloge des mairies allemandes, avec toutes les figurines. Il y a l'équivalent d'engrenages et de poulies qui exécutent tous une danse finement orchestrée. La différence essentielle est que les seuls objets importants en mouvement sont les électrons. Et la chorégraphie de la danse est le programme que le programmeur écrit après avoir été traduit en code machine. Et si le programmeur écrit quelque chose de faux et que deux des figurines s'entrechoquent, l'ordinateur suit les étapes que le programmeur a écrites et fait s'entrechoquer les figurines. Faire la mauvaise chose en programmation est appelé par euphémisme un "bug" (ou si vous êtes un programmeur sarcastique une "fonctionnalité" qui est un bug avec des lunettes de soleil prêtes pour la plage).

Donc, quand un hacker a injecté un mauvais code dans votre ordinateur, votre ordinateur lui envoie fidèlement le contenu ce que vous avez tapé sans se soucier qu'il s'agisse du mot de passe de votre compte bancaire. L'ordinateur n'est qu'une horloge mécanique qui fait ce qu'on lui dit et n'a aucune idée de l'identité du programmeur qui a créé le code (et s'en moque de toute façon). Il fait simplement ce qu'on lui dit de faire.

5) Mais, encore une fois, prenons du recul. Donc, l'ordinateur exécute "mécaniquement" certaines étapes qui font en quelque sorte apparaître un 6 sur votre écran. Comment ? Eh bien, tout d'abord, l'ordinateur a une mémoire (RAM) où il conserve des choses. Le 0110 est stocké là quelque part. L'ordinateur possède également des connexions qui lui permettent d'envoyer ces bits vers d'autres endroits, le disque, l'écran, l'internet. Ces éléments sont appelés des périphériques. Il peut également lire des données à partir de périphériques (par exemple, le disque, l'Internet, votre clavier). Donc, à ce niveau, l'ordinateur envoie le contenu de cet emplacement de la RAM à votre écran et lui dit de l'afficher.

6) Ah, mais il y a des détails importants ! Chaque périphérique a son propre langage appelé "protocole". C'est ainsi que le périphérique sait ce qu'il doit faire. L'ordinateur quand il parle à l'appareil doit "parler" ce langage. Il existe des programmes dans l'ordinateur qui indiquent à l'ordinateur comment envoyer des informations au périphérique et quel protocole il doit "parler" pour le faire. Ces programmes sont appelés pilotes de périphériques. Encore une fois, l'ordinateur lui-même ne comprend pas le protocole, c'est le programme[mer] qui le fait, l'ordinateur ne fait que suivre les étapes mécaniques qui sont codées dans ce programme.

7) Donc, faisons le point sur ce qui se passe réellement. On dit à l'ordinateur de " lancer " le programme et donc il suit les étapes du programme. Maintenant, quand il arrive à l'instruction printf, le compilateur a traduit cela en un appel à une "routine de bibliothèque d'exécution", un autre ensemble de programmes qui accompagnent le compilateur et gèrent des choses complexes à faire.

Les programmes de la bibliothèque voient le %d et connaissent les moyens de traduire le motif binaire en un nombre décimal. Comme il ne s'agit que d'un chiffre, il consulte simplement ce chiffre dans une table et voit que la lettre "6" de son alphabet est le bon choix pour ce chiffre. Il ajoute donc la lettre "6" à sa liste d'éléments à envoyer à l'écran. S'il y a d'autres chiffres, il répète le processus jusqu'à ce que tous les chiffres soient dans cette liste (appelée "tampon"). Maintenant, lorsque le tampon est plein ou que le programme se termine, le programme de la bibliothèque envoie tous les caractères du tampon au système d'exploitation qui les enverra à l'écran. Les caractères sont simplement des modèles de bits qui représentent l'alphabet des ordinateurs. Le caractère pour "6" est probablement le motif de bits 0011 0110.

Le SE cherche alors à voir quel pilote de périphérique a besoin de cette chaîne de bits et envoie la séquence de bits au pilote de périphérique qui utilise le protocole pour envoyer les bits au périphérique (l'écran).

8) Maintenant, quelque part sur ce chemin, le motif de bits pour le caractère 6, a été traduit en pixels. Cela peut se produire près de l'écran et vous envoyez des caractères à ce matériel ou cela peut se produire à l'intérieur de l'ordinateur. Wherever it happens 0011 0110 gets turned into a set of pixels—a bit pattern that looks something like this:

  1. 0000000  
  2. 0001100 .. 
  3. 0010000 . 
  4. 0111100 .... 
  5. 0100010 . . 
  6. 0100010 . . 
  7. 0011100 ... 
  8. 0000000 

You can see why I don’t design fonts for a living…..

Now, this is a very simplified version of what happens. La plupart de ces points ont des détails les gens obtiennent des diplômes et une expérience professionnelle avant de comprendre. Et, je n'ai même pas abordé les aspects d'ingénierie électrique ou de physique. Donc, ne vous attendez pas à vraiment comprendre à partir d'une question Quora comme celle-ci.

Je sais que j'ai promis des détails. Cependant, une partie de ce que je voulais écrire s'est évaporée de ma mémoire. Je peux étendre cette réponse si les gens me rappellent des détails importants que j'ai manqués et ils sont nombreux.

  1. Le complément à 2s est la façon normale dont la plupart des ordinateurs modernes ont traité l'arithmétique des "entiers". Cependant, dans les années 60, le complément à 1s était populaire. Et, vous en trouvez encore des vestiges dans le point flottant IEEE. Il y a aussi l'arithmétique BCD, l'arithmétique de magnitude signée, et toute une variété d'autres choses.
  2. La plupart des ordinateurs de nos jours utilisent soit l'ASCII soit l'Unicode comme alphabet. L'ASCII est un surensemble de l'alphabet anglais, avec également des chiffres, des signes de ponctuation et un ensemble de "caractères de contrôle" qui faisaient des choses utiles lorsque nous utilisions des télétypes. Unicode a l'ASCII comme sous-ensemble mais peut représenter la plupart des caractères utilisés dans le monde et une variété d'encodages différents, dans des tailles de 8, 16 et 32 bits (et peut-être 24 bits ?). L'UTF-8 est essentiellement l'ASCII avec une valve d'échappement pour obtenir des caractères non-latins-1 (c'est-à-dire ASCII).

    Pixels - les cellules d'image sont en fait ce dont votre écran est constitué, de petits points de couleur. La même idée est utilisée dans les écrans de télévision et l'impression et beaucoup d'autres endroits. Les bibliothèques graphiques et les frameworks graphiques vous permettent de dessiner directement des pixels et les "sprites" sont un terme pour un ensemble de pixels que vous pouvez dessiner ensemble et peut-être déplacer sur l'écran. Note, certains formats comme ceux pour dessiner des petites icônes (.BGP ?) sont essentiellement des formats de pixels, mais les formats de pixels ne sont pas la seule façon de spécifier des images.

    Les graphiques informatiques sont largement complexes et je ne prétendrai pas comprendre plus que le minimum à ce sujet.

  3. Parce que les modèles de bits des ordinateurs modernes ne sont pas spécifiquement conçus pour être lisibles par l'homme, mais plutôt pour emballer l'information la plus utile dans le moins de bits possible tout en étant facile à interpréter en actions réelles par le "décodeur" de l'ordinateur, les gens n'écrivent généralement pas le langage machine, pas à la main. La plupart des gens utilisent un langage "de haut niveau" et il en existe littéralement des centaines (surtout si l'on inclut tous les dialectes). Cependant, lorsque vous avez besoin d'un contrôle précis, en particulier des fonctionnalités qui n'ont pas d'analogue dans un langage de haut niveau, certains compilateurs permettent de "s'échapper" jusqu'au langage d'assemblage, qui est généralement une traduction un-à-un lisible par l'homme mais triviale vers le langage machine.

    De toute façon, il y a beaucoup, beaucoup de familles de langage machine. À un moment donné, je pouvais probablement écrire des langages d'assemblage pour une ou deux douzaines de familles différentes. Je suis presque sûr que je voulais énumérer un tas de langages d'assemblage représentatifs, mais je ne peux pas penser à où commencer.

    Et l'écriture d'un compilateur est définitivement un domaine entier en soi. J'ai plusieurs posts de la même longueur que celui-ci couvrant des sujets dans ce domaine.

  4. Le fait qu'un ordinateur fasse exactement ce que vous lui dites de faire et non ce que vous voulez qu'il fasse est probablement l'un des aspects les plus mal compris. De plus, les ordinateurs ne sont pas magiques. Ils sont en fait fondamentalement simples. Juste des couches sur des couches de simplicité qui finissent par les faire paraître complexes et les rendent certainement bogués, car presque aucune de ces couches n'est parfaite et certainement pas parfaitement régulière, il y a donc de nombreuses surprises qui guettent les imprudents et malheureusement il y a beaucoup, beaucoup de programmeurs imprudents.

    La sécurité informatique et les hackers/hacking est aussi son propre domaine.

  5. C'est ce qui se rapproche le plus des aspects EE (génie électrique). Mais il y a tout un catalogue de termes que l'on peut apprendre pour comprendre ces différentes parties. RAM, ROM, flip flops, registres, RAM statique v. dynamique, PROM, disques durs, disquettes, SSD, NVME, m.2, 3.5″, 2.5″, SCSI, ATE, NAS, thumb-drives, USB, RJ45, .... et je n'ai même pas effleuré la surface.
  6. Les pilotes de périphériques et les protocoles sont un sujet entier en soi. Je pense en avoir écrit un, une fois. Il y a des classes entières dans les protocoles de réseau.
  7. Écrire une bibliothèque d'exécution ou un cadre d'application est une tâche majeure. Au niveau professionnel, il y a généralement une équipe qui en est responsable. C'est la même chose pour un système d'exploitation.