L'étape finale consistant à transcrire du langage informatique en 0 et 1 s'appelle «compiler». Ça se fait avec un compilateur (qui est un programme) à qui l'on donne notre code informatique (on dit aussi « code source »). À l'issue de la compilation, on obtient ce qu'on appelle un «binaire» (car il est fait de 0 et de 1).
Par exemple, un fichier .exe sur votre Windows, c'est un binaire.
Alors si vous essayez de l'ouvrir avec un éditeur de texte, vous n'allez pas voir les 0 et les 1. Ça va plutôt ressembler à ça :
\B9\6C\70\A5\0A\08\08\11\F0\E2\64\00\00\00\00\00\08\17\72\00\00\00\00\00\BA\57\00\00\00\00\00\00\A0\30\66\00\00\00\00\00\60\FC\65\00\00\00\00\00\40\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00Car les ordinateurs lisent les 0 et 1 (les bits) par paquets de 8 qu'on appelle des octets (bytes en anglais), avec une représentation où 00000000 s'écrit \00 et 11111111 s'écrit \FF.
Et finalement votre processeur (le truc qui, à la toute fin de la toute fin, exécute les instructions) il a des règles pour dire "tel octet c'est quand je dois faire ci, tel octet c'est quand je dois faire ça".
On peut obtenir une vue de ce que comprend un processeur, lorsqu'il voit un binaire, avec un « désassembleur » qui est un programme remplaçant les octets par leur équivalent en instructions du processeur (ce qui se nomme le « langage assembleur »).
Pour notre programme de sortie d'un labyrinthe, ça donnerait quelque chose comme ça :
0000000000400000 <_start>:
400000: b9400021 ldr w1, [x1, #0]
400004: 7100003f cmp w1, #0x0
400008: 54000080 b.eq 0x400028 <coursive>
40000c: 7100043f cmp w1, #0x1
400010: 54000100 b.eq 0x400030 <embranchement>
400014: 7100083f cmp w1, #0x2
400018: 54000180 b.eq 0x400050 <culdesac>
40001c: 71000c3f cmp w1, #0x3
400020: 54000200 b.eq 0x400070 <sortie>
400024: 17fffff2 b 0x400000 <_start>
0000000000400028 <coursive>:
400028: 94000004 bl 0x400080 <avancer>
40002c: 17fffff0 b 0x400000 <_start>
0000000000400030 <embranchement>:
400030: b9400040 ldr w0, [x2, #0]
400034: 51000400 sub w0, w0, #0x1
400038: b9000040 str w0, [x2, #0]
40003c: 94000003 bl 0x400080 <avancer>
400040: 17ffffec b 0x400000 <_start>
0000000000400050 <culdesac>:
400050: b9400040 ldr w0, [x2, #0]
400054: 51000800 sub w0, w0, #0x2
400058: b9000040 str w0, [x2, #0]
40005c: 94000002 bl 0x400080 <avancer>
400060: 17ffffe8 b 0x400000 <_start>
0000000000400070 <sortie>:
400070: d2800000 mov x0, #0x0
400074: d2800ba8 mov x8, #0x5d
400078: d4000001 svc #0x0
0000000000400080 <avancer>:
400080: d65f03c0 retNormalement là votre premier réflexe c'est de dire "non mais notre algorithme il faisait trois lignes, notre code il en faisait 12 et là ton truc il en fait 32 !".
OUI ! À chaque étape on va plus loin dans le détail. Pour vous donner un ordre d'idée, faire une addition en langage informatique ça prend une ligne : a=1+2. En langage assembleur ça en prend 5 :
Et ça ressemble à quelque chose comme ça :
ADRP X1, a
MOV W0, #1
MOV W1, #2
ADD W0, W0, W1
STR W0, [X1] Ce que j'ai vulgairement appelé les cases (qui s'appellent en réalité des registres) sont un peu comme des bols pendant que vous cuisinez : vous coupez des poivrons sur votre planche à découper puis vous les mettez dans un bol pour avoir cette planche disponible pour la découpe des oignons. Ça sert à stocker les résultats intermédiaires.
Votre second réflexe c'est de vous dire "la vache on comprend vraiment rien à ce qui est marqué là". C'est normal c'est fait pour être lu par le processeur, pas par un humain. Donc il n'y a pas de besoin que ce soit compréhensible.