Si tu veux, au début on écrivait directement en binaire, avec des câbles et des interrupteurs.
Le programmeur connaissait les instructions binaire que la machine attendait, donc il écrivait son programme et celui ci pouvait directement être exécuté (enfin, après l'avoir fait passer de la feuille de papier a la machine, ce qui prenait très longtemps parfois)
Ensuite, on a créer l'assembleur. L'assembleur est un langage très proche du langage machine, puisque pour chaque intruction en assembleur, il existe une instruction du langage machine. On peut facilement passer le l'un a l'autre, mais l'un ressemble a "MOVE 345,4(3:4)" et l'autre a "000010001011100"
Le premier assembleur était en fait des humains, qui faisait la traduction. Puis quelqu'un a ecrit un programme qui le faisait, le premier "Assembleur".
Les premiers compilateurs a avoir été écris on donc été écrit en assembleur/langage machine (en fait, c'est un peu la même chose)
Sauf qu'au bout d'un moment, on obtient un langage suffisamment puissant pour qu'on puisse écrire le compilateur de ce langage, dans ce langage ! Ca a été le cas du C.
Maintenant, les compilateurs C sont écrits en C (par exemple GCC), et on les compiles avec la version d'avant, elle même compilé avec celle d'avant, etc...
En effet, écrire un compilateur complet pour les langage modernes (et qui optimise les programmes) directement en assembleur est trop complexe.
===
Ensuite, si tu remonte très loin dans les détail de la machines, ca dépend. Si tu veux, par example, dans minecraft on peut construire un ordinateur avec uniquement des portes logiques XOR. Mais d'autres architectures utilisent d'autres portes logiques, donc ca depend de ta machine. Après, en réalité on utilise plus le CPU comme une machine qui sait faire des XOR, des sommes, deplacer de la mémoire, etc, sans se préoccuper de comment les électroniciens ont vraiment réaliser le bouzin...
Parce qu’en vrai, un ordinateur ca gère des séries de 0 et de 1, pas juste chacun d'entre eux séparé. L'unité de base des opération d'un ordinateur est appellé le Byte. De nos jours un byte est égal a un octet (8 bit, cad huit 0 ou 1) sur la 99.999% des machines, mais au début de l'informatique (et jusque dans les années 90), les bytes n'avait souvent pas la même taille entre deux machines