Comment passe-t-on exactement des ensembles d'instructions binaires / hexadécimales aux instructions d'assemblage?


13

J'ai donc essayé d'apprendre la programmation Embedded / Assembly un peu ici ces derniers temps, tout en allant jusqu'à essayer d'apprendre le niveau le plus bas (portes et autres).

Une chose me laisse perplexe cependant ... est de savoir comment "obtenir" des jeux d'instructions. Je comprends un peu comment fonctionnent les portes / TTL et autres, mais je ne vois pas comment nous pouvons passer de ça à mov, add, clr etc ...?

C'est probablement une question stupide .... mais je veux dire que je repense aux premiers micro-processeurs / contrôleurs et pense ... comment exactement ont-ils conçu un jeu d'instructions et l'ont fait fonctionner?

edit: Je suppose que pour Clarity, je fais semblant de parler du premier microprocesseur, comment sont-ils passés du binaire à la création d'un jeu d'instructions?


2
Chaque instruction a une valeur, le compilateur convertit votre code en ces instructions, en fonction de la structure de votre code.
Ramhound

1
Je ne sais pas si je comprends parfaitement votre question, mais je pense que vous pouvez trouver votre réponse ici , ici ou ici .
e-MEE du


3
comment sont-ils passés du binaire à la création d'un jeu d'instructions? En fait, «ils» ne l'ont pas fait - c'est l'inverse, du moins en général. Le ou les concepteurs de CPU déterminent les opérations que le CPU effectuera, puis ils créent le jeu d'instructions à partir de cela, puis ils mappent les instructions (mnémoniques) aux opcodes (code machine binaire). @Scott Whitlock a fourni une bonne réponse ci-dessous, je voulais juste répondre à la dernière partie de votre question parce que votre hypothèse, du moins d'après mon expérience, est à l'envers.
Radian

1
Ce livre vraiment sympa: www1.idc.ac.il/tecs est ce qui m'a tout expliqué, la plupart des chapitres sont disponibles gratuitement en ligne. Vous concevez votre propre puce (dans un langage de description matérielle simple) à partir de nand gates, puis un assembleur puis un compilateur, puis écrivez un os dans la langue que vous avez créée! Des choses incroyables, et en tant que personne sans diplôme en science-fiction, c'était du temps bien passé pour moi!
bplus

Réponses:


18

Le cœur d'un CPU est l' ALU . Il est responsable de prendre une instruction (comme MOV) qui est juste une série prédéfinie de chiffres binaires, et aussi de prendre 0, 1 ou 2 opérandes, et d'effectuer l'opération applicable sur eux. L'instruction la plus simple pourrait être un NOP (aucune opération) qui ne fait essentiellement rien. Une autre opération typique est ADD (ajoute deux valeurs).

L'ALU lit et écrit des données depuis et vers des "registres". Ce sont de petits emplacements de mémoire internes au CPU. Une partie de l'instruction (2 à 3 bits pour chaque entrée selon le nombre de registres dont vous disposez) indique le registre dans lequel lire. Il existe des unités dans le processeur externes à l'ALU qui gèrent le chargement des données requises (et l'instruction) de la mémoire dans les registres et l'écriture du résultat des registres dans la mémoire. L'emplacement où écrire le résultat sera également codé sur 2 ou 3 bits supplémentaires.

Le choix des "codes op", qui est le nombre binaire qui représente une opération, n'est pas arbitraire. Des opcodes bien choisis réduisent la complexité de l'ALU. Chaque bit ou groupe de bits a tendance à activer et désactiver certaines portes logiques dans l'ALU. Par exemple, une instruction ADD devrait permettre à l'étage de sortie de choisir le résultat de la logique d'ajout interne. De même, une instruction MUL choisirait le résultat de la logique de multiplication. Selon la conception, il est fort probable que les circuits additionneur et multiplicateur effectuent tous les deux leur fonctionnement sur les opérandes d'entrée, et c'est juste la sélection de sortie (ce qui est écrit dans les bits de sortie de l'ALU) qui change.


1
Je suppose que ce que je demande, c'est comment choisissent-ils? Et comment font-ils pour l'attribuer?

1
@Sauron: Relisez à nouveau le 3e paragraphe et essayez de comprendre les circuits arithmétiques et numériques binaires. Je peux représenter un ensemble d'instructions avec 256 instructions par une ligne 8 bits dans un circuit numérique. Cela signifie que j'ai besoin de 8 ports io sur mes périphériques matériels pour transférer tous les états possibles (2 états par ligne ^ 8 lignes = 256 états possibles). L'unité de traitement peut alors décider quoi faire de ce signal d'entrée numérique. Un circuit numérique signifie que vous avez deux états matériels: Hi et Lo, tension ou pas de tension. C'est de là que vient le binaire. La représentation binaire est la plus proche du métal.
Falcon

3
@Sauron - recherchez des multiplexeurs numériques pour voir comment un circuit numérique peut choisir parmi plusieurs valeurs. Si vous avez un bus 8 bits, vous avez juste besoin de 8 de ces multiplexeurs numériques binaires en parallèle.
Scott Whitlock, le

1
@Falcon Ok ....... Je pense que cela a plus de sens. J'oublie toujours qu'en fin de compte, tout revient aux signaux binaires ... et même une instruction telle que "mov" est toujours représentée comme binaire.

1
@Sauron - Faites des recherches sur le CPU, cela vous aidera à comprendre ce que sont les codes op et comment ils fonctionnent. Pourquoi certains codes op sont choisis n'est pas important, même poser la question «pourquoi» n'a pas beaucoup de sens. Comprendre comment ils sont choisis pourrait vous aider à mieux comprendre le CPU et sa structure.
Ramhound

9

Je vais prendre votre question au pied de la lettre et discuter principalement des microprocesseurs, pas des ordinateurs en général.

Tous les ordinateurs ont une sorte de code machine. Une instruction se compose d'un opcode et d'un ou plusieurs opérandes. Par exemple, l'instruction ADD pour l'Intel 4004 (le tout premier microprocesseur) a été codée comme 1000RRRR où 1000 est l'opcode pour ADD et RRRR représentait un numéro de registre 0-15 (0000-1111 en binaire).

Toutes les autres instructions faisant référence à l'un des 16 registres 4 bits (tels que INC, ISZ, LD, SUB, XCHG) utilisent également les 4 bits bas pour coder le numéro de registre, et divers codages des 4 bits supérieurs pour spécifier l'opcode. Par exemple, ADD, SUB, LD et XCHG utilisent les opcodes 1000, 1001, 1010 et 1011 (tous en binaire) combinés avec le champ de registre. Vous pouvez donc voir comment un modèle est utilisé pour simplifier la logique.

Les tout premiers programmes informatiques ont été écrits à la main, encodant à la main les 1 et les 0 pour créer un programme en langage machine. Celui-ci a ensuite été programmé dans une ROM (mémoire morte). Désormais, les programmes sont généralement écrits dans une mémoire Flash effaçable électriquement, dans le cas des microcontrôleurs, ou à court de RAM, si les microprocesseurs. (Ce dernier a toujours besoin d'une sorte de mémoire morte pour le démarrage.)

Le langage machine devient fastidieux très rapidement, donc des programmes d'assemblage ont été développés qui prennent un langage assembleur mnémonique et le traduisent, généralement une ligne de code d'assemblage par instruction, en code machine. Donc au lieu de 10000001, on écrirait ADD R1.

Mais le tout premier assembleur devait être écrit en code machine. Ensuite, il pourrait être réécrit dans son propre code assembleur, et la version en langage machine utilisée pour l'assembler la première fois. Après cela, le programme pourrait s'assembler (c'est ce qu'on appelle le bootstrapping).

Étant donné que le premier microprocesseur a été développé longtemps après les ordinateurs centraux et les mini-ordinateurs, et que le 4004 n'était pas vraiment adapté pour exécuter un assembleur de toute façon, Intel a probablement écrit un assembleur croisé qui fonctionnait sur l'un de ses gros ordinateurs et a traduit le code d'assemblage pour le 4004 en une image binaire qui pourrait être programmée dans les ROM.


4

Un ordinateur à un niveau très bas peut être représenté par un chemin de données et un contrôle . Les rechercher ensemble peut vous donner beaucoup de lecture car c'est fondamental dans l'architecture / la conception numérique.

Je ferai de mon mieux pour résumer:

Comme mentionné ici, au cœur, nous avons une ALU - ce qu'il faut savoir sur l'ALU (et d'autres parties du CPU), c'est qu'il est reconfigurable pour différentes opérations. Plus précisément, nous avons la possibilité de reconfigurer le chemin de données , c'est-à-dire comment les paramètres sont récupérés, quelle opération faire et où ils sont stockés par la suite. Imaginez être capable de manipuler ces trois choses - c'est notre contrôle .

Alors, comment pouvons-nous accomplir cela? Comme mentionné précédemment, nous pouvons tirer parti de la logique numérique de bas niveau et créer des multiplexeurs pour différents chemins. Les multiplexeurs sont contrôlés à l'aide d'un ensemble de bits pour l'entrée - d'où proviennent ces bits? Encodé à partir des instructions elles-mêmes. À retenir: des instructions telles que mov, add, etc. ne sont qu'un ensemble de bits qui indiquent à un processeur comment configurer son chemin de données pour une opération particulière. Ce que vous lisez (mov, add) est la forme lisible par l'homme (langage d'assemblage) et notre programme définit une procédure de chemins de données et d'opérations.

Je m'excuse s'il s'agit d'une simplification excessive de processus plus complexes pour ceux qui sont mieux informés dans ce domaine. Pour info, l'échange de piles de génie électrique serait un excellent endroit pour poser cette question car il traite de la logique de très bas niveau.


3

si je comprends votre question, je ne comprends pas comment le bin / hex ou l'assemblage sont liés.

Je suppose que la viande de votre question est de savoir comment obtenir des portes de base, ET, OU, PAS à des instructions telles que déplacer, charger, stocker, ajouter, etc.

J'ai mon propre petit ensemble d'instructions pédagogiques que j'ai créé à partir de zéro qui contient certains détails sur la façon dont un ajout et une soustraction fonctionnent sur des portes de base et des choses comme ça http://github.com/dwelch67/lsasim .

Recherchez le livre Code (quelque chose quelque chose quelque chose) de Petzold. Peut commencer le chemin de l'élémentaire mais vous fait passer lentement de rien à voir avec les ordinateurs et l'électronique en binaire, hexadécimal et dans les portes de base, etc.

Demandez-vous comment vous en construiriez un à partir de zéro aujourd'hui, ou comment l'ont-ils fait à l'époque? Aujourd'hui, vous commenceriez par une définition du jeu d'instructions. vous venez de vous asseoir et de l'écrire, vous pensez aux types d'instructions que vous devez avoir les charges et les magasins et les mouvements et les trucs alu, puis combien de registres, la taille des registres, cela affecte en partie la taille de l'instruction, vous pensez sur la taille de l'instruction ...

Permettez-moi de vous arrêter et de vous demander comment écrivez-vous un programme? Vous commencez avec un écran vide sur un éditeur de texte? Vous avez une idée de la tâche que vous essayez de résoudre les variables dont vous pourriez avoir besoin, les fonctions, le langage de programmation, etc. Et chaque personne est différente, mais dans une certaine mesure, vous faites un peu de cela (par exemple définir et écrire des fonctions), un peu de cela (faire des fichiers d'en-tête avec des définitions et des énumérations et des structures et des trucs réutilisables), et un peu d'autre chose (juste coder, remplir les fonctions avec des variables et du code). Et vous circulez autour des différentes tâches, à la fin vous sentez que vous avez un équilibre entre la taille du code, la vitesse, la lisibilité, la qualité, la fonctionnalité, etc. Pas de différence avec la conception matérielle. les concepteurs de matériel utilisent également des langages de programmation (vhdl, verilog) et suivent le même processus,

Tout comme créer un logiciel, vous équilibrez les désirs, les performances, la taille, les fonctionnalités, etc. Vous pourriez avoir à vous imposer des règles de conception que vous vouliez ou que votre patron vous a fait faire, etc. Comme pour la conception de logiciels bien après de la conception initiale à la mise en œuvre, vous découvrirez peut-être que vous avez de grosses erreurs et que vous devez revenir à la conception initiale et modifier le jeu d'instructions, des changements petits ou grands. Pourrait arriver à avoir un compilateur et un processeur simulé pour vous trouver vraiment besoin de quelques instructions spécifiques qui améliorent considérablement la qualité du code compilé, les performances, etc.

Vous avez donc inventé un jeu d'instructions à partir de zéro, vous avez utilisé une certaine expérience de la conception matérielle pour regrouper des instructions similaires avec des modèles de bits similaires afin qu'elles puissent être décodées plus facilement, pas seulement pour la programmation en langage matériel, mais cela économise de l'énergie et des portes et tout ce qui Bon produit. Ces jours-ci, vous feriez une sorte de simulateur, d'après ce que je comprends, ARM était d'abord un simulateur logiciel, puis les conceptions matérielles sont venues plus tard, je ne sais pas si c'est vrai, mais respectant cette histoire. Cela dépend de l'équipe, certaines équipes peuvent être uniquement des personnes matérielles et veulent simplement entrer dans la programmation en hdl, certaines comme moi peuvent vouloir faire un peu des deux. De nos jours, de bons simulateurs de langage matériel sont disponibles, vous n'avez donc pas à construire de matériel que vous compilez et simulez et effectuez une grande partie de votre débogage avec un programme / package de simulation matérielle. l'équipe logicielle peut développer des assembleurs et des compilateurs pour le jeu d'instructions et utiliser des programmes d'alimentation ram et rom simulés pour le processeur simulé et le mettre à l'épreuve. nous avons simulé un démarrage linux complet sur un processeur sur lequel j'ai travaillé il n'y a pas longtemps, a pris plusieurs heures mais cela a fonctionné (trouvé un bug de cache dans la logique de cette façon).

Alors maintenant, pour ce que je pense vraiment que vous demandiez. Comment passer des portes de base à un processeur avec un jeu d'instructions. Les portes de base ET ET OU NE SONT PAS vraiment analogiques, elles n'ont pas de notion de temps, vous ne pouvez pas changer instantanément la tension sur les entrées et lorsque vous changez cette tension, les sorties commencent à changer. les grilles sont constituées de transistors et les transistors sont des amplificateurs, prenez l'entrée, multipliez-la par un certain nombre et laissez passer autant de courant de l'autre côté. lorsque nous les utilisons comme portes logiques, nous les sursaturons en fait, la tension d'entrée est si élevée ou basse que le transistor ne peut piloter que la tension maximale ou aucune tension (courant). fondamentalement, le transitor est transformé en interrupteur. Bref, il n'y a pas de notion de temps. Afin d'avoir un ensemble d'instructions, nous devons avoir des instructions pour que nous ayons à séquencer le programme, nous devons avoir un concept maintenant que nous sommes sur cette instruction, et dans la prochaine tranche de temps, nous travaillerons sur cette instruction. Tout comme le jeu de transformer un amplificateur en interrupteur, vous jouez à des jeux similaires en utilisant des portes logiques de base avec une horloge. les horloges proviennent de cristaux magiques dans une boîte (cela ne vaut pas la peine d'entrer ici) qui créent des tensions qui s'allument et s'éteignent à un taux fixe. utilisez cette tension dans des équations logiques et vous pouvez commencer à séquencer les choses. les horloges proviennent de cristaux magiques dans une boîte (cela ne vaut pas la peine d'entrer ici) qui créent des tensions qui s'allument et s'éteignent à un taux fixe. utilisez cette tension dans des équations logiques et vous pouvez commencer à séquencer les choses. les horloges proviennent de cristaux magiques dans une boîte (cela ne vaut pas la peine d'entrer ici) qui créent des tensions qui s'allument et s'éteignent à un taux fixe. utilisez cette tension dans des équations logiques et vous pouvez commencer à séquencer les choses.

pense très très brièvement à cette table de vérité:

0 0 0
0 1 1
1 0 1
1 1 0

en binaire:

0 + 0 = 1
0 + 1 = 1
1 + 0 = 1
1 + 1 = 10 (2 decimal)

en se concentrant uniquement sur le lsbit, un additionneur d'un bit, la table de vérité ci-dessus décrit un additionneur d'un bit. Il décrit également une porte XOR. Une entrée est vraie ou l'autre mais pas les deux.

Pour obtenir plus d'un bit, vous devez regarder les bits de retenue et les exécuter et vous avez besoin d'un additionneur de trois bits, de deux opérandes et d'un transfert avec deux sorties, effectuer et le résultat. Une fois que vous avez cet additionneur à trois entrées et deux sorties, vous pouvez le mettre en cascade aussi large que vous le souhaitez. Mais c'est toujours analogique, les portes changent instantanément.

Comment vous transformez cet additionneur analogique en une instruction ADD, c'est que vous avez une logique qui regarde l'instruction qui se trouve en entrée de ces portes que vous avez arrangées. certains des bits de l'instruction disent, il s'agit d'une instruction d'ajout, certains des bits disent qu'un opérande est tel ou tel registre, peut-être le registre 7, d'autres bits peuvent dire que l'autre opérande est le registre 4. et selon l'architecture que vous pourrait avoir un autre registre défini dans l'instruction qui dit mettre le résultat dans le registre 2. Maintenant, plus de logique voit cela car j'ai besoin que le contenu du registre 7 soit acheminé vers une entrée de l'additionneur alu et que les entrées du registre 4 soient acheminées vers l'additionneur, et vous acheminez la sortie de l'additionneur à enregistrer 2. Étant donné que l'horloge fait partie de cette logique, il existe une période de temps allant du début de la période d'horloge au début de la période d'horloge suivante où tous les signaux analogiques se stabilisent et résolvent l'équation logique qu'ils sont câblés. Un peu comme lorsque vous actionnez un interrupteur d'éclairage, vous changez l'état de l'éclairage de désactivé à activé. il faut un certain temps pour que cette lumière se réchauffe et se mette à l'état stable. Pas très différent ici.

Il y a une logique qui dit des choses comme si cette période d'horloge est la phase d'exécution d'une instruction AND, alors la prochaine période d'horloge que je vais enregistrer le résultat dans le registre de sortie. en même temps, je vais chercher l'instruction suivante, etc. Donc, pour les processeurs modernes où l'exécution alu n'est souvent qu'une période d'horloge car la logique analogique peut résoudre les équations logiques aussi rapidement. Les processeurs plus anciens que vous deviez compter jusqu'à un certain nombre laissent l'additionneur branché, attendez x nombre de cycles d'horloge pour que la logique de l'additionneur se résolve, puis échantillonnez le résultat de la sortie, alimentez les différentes entrées alu, attendez x nombre de cycles d'horloge pendant que pour résoudre, répéter pour toujours ou jusqu'à ce que le courant soit coupé.

Qu'est-ce que j'entends par équations logiques? juste cela, si vous voulez, vous pouvez le penser en termes de portes ET, OU, PAS. Pour chaque bit d'entrée du circuit additionneur alu, il existe une équation, probablement une très longue équation qui comprend l'horloge, qui comprend les bascules (bits de mémoire individuels / simples) qui contiennent l'instruction en cours (plus les équations qui alimentent chacune de ces bits de mémoire) et ainsi de suite. Prenez une seule fonction logicielle que vous avez écrite, dans la langue que vous l'avez écrite, en supposant qu'il s'agit d'une fonction qui prend les entrées, exécute une tâche, puis termine et retourne un résultat. Pensez à toutes les combinaisons possibles d'entrées et quels sont les différents chemins d'exécution à travers cette fonction. Vous l'avez peut-être écrit dans un langage de haut niveau, mais vous pourriez probablement même le réécrire dans ce langage pour le rendre plus primitif et plus primitif en utilisant de nombreuses structures imbriquées if-then-else. et aller plus bas dans le langage d'assemblage peut-être. À la différence des équations dont je parle, le programmeur matériel ne programme pas plus dans ces équations longues que vous ne programmez probablement dans des arbres si-alors-sinon longs en langage assembleur lorsque le langage de programmation de votre choix vous permet d'économiser tant de choses. Tout comme le compilateur que vous utilisez transforme votre petit code source en assemblage de longue haleine avec beaucoup de if-then-elses, il existe un compilateur qui prend le code du langage de programmation matériel et le transforme en équations logiques.

Revenons maintenant au premier processeur (que nous considérons aujourd'hui comme un microcontrôleur, mais c'était un processeur). Vous avez fait tout ce qui précède sur papier, et vous n'avez pas utilisé de langages de programmation matériels, vous avez en fait écrit les équations logiques, mais vous avez encore plus soigneusement choisi les modèles de bits pour les instructions afin de rendre le nombre de portes et les fils pour connecter ces portes aussi simples aussi pratique. Sur le papier, à la main, vous deviez à la fois créer la longue liste de portes logiques câblées, puis dessiner les composants réels sur une version explosée du masque de silicium. même aujourd'hui, les puces sont fabriquées en utilisant ce qui est similaire à un processus photographique ou sérigraphique en termes profanes, vous devriez donc prendre ces impressions bleues si vous le souhaitez et les rétrécir, puis les appliquer sur les couches de silicium.

là encore, à l'époque, tout le monde avait une meilleure maîtrise de l'assemblage et non seulement vous pourriez finir par faire de la programmation d'assemblage, vous pourriez ne pas avoir d'éditeur de texte ni d'assembleur, vous auriez pu avoir à écrire vos premiers programmes à la main sur papier, puis à l'aide d'un manuel de référence, converti à la main en code machine, uns et zéros. Sur certains de ces ordinateurs, vous pourriez avoir dû charger le ram en actionnant des commutateurs, en inversant les bits d'adresse, en inversant les bits de données jusqu'à ce qu'ils correspondent aux nombres sur votre papier, en inversant puis en baissant le bit d'horloge et en chargeant un emplacement de mémoire avec un octet d'une instruction de votre programme, répétez quelques centaines de fois plus et j'espère que vous ne ferez aucune erreur.

De la même manière que le premier permet de dire que le compilateur C a probablement été écrit dans un autre langage, il est devenu auto-hébergé en étant réécrit en C et compilé par le premier compilateur C puis de nouveau par lui-même. Ensuite, les compilateurs C ont été utilisés pour inventer d'autres langages de programmation qui sont ensuite devenus auto-hébergés. Nous avons inventé des systèmes d'exploitation et des éditeurs de texte qui se sont construits sur eux-mêmes, et c'est toute la magie noire laissée à quelques personnes derrière le rideau dans le coin à faire ...

oui, très long, c'est une grande question qui nécessite des années d'études et d'expérience pour vraiment comprendre. regardez mon lsasim, je ne prétends pas être un expert en quoi que ce soit, mais c'est un jeu d'instructions, il y a à la fois un simulateur qui exécute l'instruction écrite en C, et une autre implémentation du processeur implémentée dans un langage de programmation matériel qui peut être simulé à l'aide de différents outils. Plus un assembleur brut et quelques autres outils et autres. Peut-être qu'en examinant certains de ces éléments, en particulier le code du langage de programmation matériel, cela pourrait combler l'écart sur ce que je suppose que vous demandiez. Si je n'ai pas comblé cet écart ou si j'ai créé une tangente de longue haleine, faites-le moi savoir que je supprimerai volontiers cette réponse (en supposant que je suis capable de ne pas passer beaucoup de temps à échanger des programmeurs).


Cela ne répond vraiment pas à la question de l'auteur, au moins n'ajoute rien à la discussion, que la réponse acceptée ne couvre pas. Vos calculs binaires ne sont pas corrects à 100% 1 + 1 est 0 avec un débordement de 1. Selon la taille du registre, ce serait soit 2 soit 0.
Ramhound

@dwelch DAMN! Je suis votre fan de cœur si rien de moins. +1
AceofSpades

2

Les processeurs fonctionnent sur 0 et 1. Toutes les instructions avaient une séquence de bits qui les définissait. Thsi était le code machine. C'est difficile pour les humains de lire et d'écrire. Dans un premier temps, nous avons regroupé les 0 et les 1 en séquences de 4 bits et utilisé de 0 à F pour les représenter. Cela a réduit les nombres que nous devions mémoriser, mais il n'était toujours pas facile de se souvenir du code hexadécimal pour obtenir des instructions.

Nous avons donc commencé à utiliser l'assemblage qui avait des «mots» comme MOV et ADD. L'assembleur remplacerait les instructions par l'ensemble correct de 0 'et 1 convertissant l'assemblage "listant" en code machine.

Finalement, nous avons développé des langages de niveau "supérieur" où les "instructions" pouvaient représenter des séquences entières de code machine.


Pour info, octal a été utilisé comme raccourci binaire avant hexadécimal.
ocodo

Slomojo est à droite, Octal, base 8 utilisé 3 bits, a été utilisé avec hex, base 16 utilisé 4 bits. Octal avait l'avantage en ce que tout le monde savait ce que représentaient les numéros 0 à 7. Les gens qui n'utilisaient pas Hex étaient souvent mystifiés par les "chiffres" A à F.
Jim C

0

J'ai récemment rencontré ce Q / R et il y a environ un an environ quand j'ai commencé à voyager dans cette voie; J'aurais trouvé que c'était une très bonne ressource et une page de référence en ce qui concerne mes propres questions.


Partie 1: -Préface-

Un peu de moi:

Entre le milieu et la fin des années 80, alors que j'étais encore à l'école primaire, je démontais les stéréos indésirables, les magnétoscopes et autres appareils à électrons des années 50 aux années 80 et je regardais les circuits imprimés et je voulais toujours savoir comment travailler ... Comment ont-ils réellement acquis le signal de diffusion, produit de l'audio, de la vidéo, fait ceci et cela, etc. savent ce qu'ils ont fait ou comment ils ont fonctionné à un si jeune âge.

Au fil des ans, j'ai toujours été exceptionnel en mathématiques, physique et chimie. J'ai compris les mathématiques à un haut degré et je pouvais même lire des circuits simples ou basiques de mes années de collège et de lycée qui sont venus plus tard, mais je n'ai jamais réussi à en apprendre davantage sur les portes logiques et comment elles ont été construites ... apprendre l'algèbre booléenne au lycée de mon cours de logique, probabilités et statistiques. Tous mes cours de mathématiques et de sciences étaient des cours de spécialisation. Je n'ai pas pris de calcul avant mon deuxième semestre dans un collège communautaire. J'ai testé le Collège d'Algèbre et pris la Trigonométrie comme un cours de recyclage. Mon plus haut niveau de mathématiques en classe est le calcul II d'une seule variable.

Je joue aux jeux vidéo depuis l'âge de 3 ou 4 ans. Enfant, j'avais l'Atari, la NES, la Sega Genesis et la PS1. En vieillissant et à la fin de mon adolescence et au début de la vingtaine, j'avais acquis la PS2 et la SNES avec des titres sélectionnés préférés. Cela ne tient pas compte non plus des jeux sur PC qui remontent à Doom!

J'ai toujours été un passionné de console et de PC et cela n'inclut pas les jeux de flipper et d'arcade.

On m'a donné mon premier PC quand j'avais environ 12 ans pour Noël au début des années 90. Les jours de DOS 6.0 et Win 3.11 ou OS / 2. Depuis lors, j'ai toujours été familier avec la famille de systèmes d'exploitation "Windows" et tous les systèmes que j'ai eu étaient Intel Architecture. J'ai eu une expérience limitée avec Apple ou Mac de l'école ou du collège, mais je n'ai jamais eu le privilège de travailler sur des systèmes Linux. J'ai Cygwin et j'ai essayé d'apprendre bash, mais je suis tellement habitué à Dos ou à la syntaxe d'invite de commandes.

Au début des années 90, j'obtenais une copie ou deux de PC-World et je tapais les extraits de code dans QBasic que je ne connaissais pas très bien et j'essayais de faire fonctionner ces programmes. Le seul qui a réussi a été un programme pour transformer les appuis sur les touches de la rangée de touches principale en différents sons de sonnerie. Je ne veux pas dire les sonneries sur un téléphone portable, je veux dire une fréquence continue tant que vous maintenez la touche enfoncée.

Ça a toujours été une passion pour moi non seulement de vouloir savoir comment les appareils électroniques fonctionnaient au sein de la circuité au niveau numérique et logique, d'apprendre à programmer un ordinateur, mais j'ai toujours eu le désir de vouloir faire ma propre vidéo Jeux. Même au début des années 90, je voulais faire les jeux Frogger et Tetris ...


Cela est devenu ma principale motivation et mon désir d'aborder l'un des types de programmation ou de développement de logiciels les plus difficiles dans le domaine de l'informatique, à savoir la conception de moteurs de jeux 3D. Il existe d'autres domaines en informatique qui sont tout aussi difficiles, mais tous les moteurs de jeu sophistiqués les incluront généralement ou généralement presque tous, car les composants ou sous-moteurs individuels nécessitent leurs techniques et / ou leurs propriétés.

J'avais des antécédents en programmation depuis mes jours de lycée, mais cela se limitait à l'horrible Visual Basic. J'ai commencé à apprendre et à apprendre le C / C ++ vers 2002 - 2003, seulement quelques années après avoir obtenu mon diplôme d'études secondaires en 1999. Même à ce jour, je n'ai aucune expérience universitaire en informatique ou en génie informatique, mais grâce à dévouement et détermination, j'ai appris à peu près tous les concepts qui existent en matière d'ordinateurs, de matériel, de programmation, d'algorithmes, etc. et je continue d'apprendre autant que je peux ...

Au tout début de l'apprentissage du C / C ++, j'avais accès à Internet mais Internet n'en était qu'à ses débuts, des sites comme Amazon, Youtube, Facebook etc. n'existaient même pas encore, c'était encore l'époque du 56k composez des modems qui marchent votre ligne téléphonique si vous n'avez pas de deuxième ligne dédiée. Cela prendrait des minutes juste pour qu'une image soit rendue à l'écran, sans parler de la lecture vidéo continue.

Ainsi, en ce qui concerne la recherche et l'apprentissage de la programmation en C ++, les ressources étaient limitées et la plupart étaient au format texte. En tentant de s'attaquer aux projets dès les premiers jours du didacticiel sur Internet, bon nombre de ces projets n'étaient pas entièrement terminés, les auteurs étaient soit des professionnels, soit des étudiants et ils avaient fait de nombreuses hypothèses selon lesquelles le lecteur connaissait déjà bon nombre des concepts nécessaires tels que la compilation , liaison et débogage et intégration de bibliothèque.

Pour quelqu'un qui ne sait rien de ces sujets, ils sont perdus parce qu'ils ne savent pas ce qui s'est mal passé, ni comment y remédier, ni comment le faire fonctionner correctement. Cela m'a pris de nombreuses heures d'essais et d'erreurs à cette époque avec des ressources très limitées. Demander de l'aide telle que nous pouvons maintenant avec ce site Web ou chercher des explications détaillées que vous pouvez trouver sur cppreference n'était pas disponible! Si vous ne connaissiez personnellement personne, vous ne pouviez pas vous adresser à beaucoup pour obtenir de l'aide!

Au fil du temps, j'ai amélioré certaines de mes connaissances ici et là, et finalement Internet s'est amélioré en DSL, et maintenant Internet haute vitesse, les sites Web sont devenus plus interactifs, les vidéos ont commencé à apparaître, la qualité des vidéos s'est améliorée avec le temps, des sites tels que lorsque Youtube a commencé à apparaître et que les choses sont devenues un peu plus faciles du côté de la recherche. De plus en plus de tutoriels sont devenus facilement disponibles, certains étaient bons et utiles là où d'autres enseignaient les mauvaises pratiques ...

J'avais également passé beaucoup de temps à trouver et à acquérir les outils nécessaires au développement. J'ai dû apprendre la syntaxe du langage, le compilateur et le processus de compilation, la liaison, la construction et le débogage. Ensuite, j'ai dû en apprendre davantage sur les différentes bibliothèques et API disponibles et comment configurer mes projets ou solutions pour lier toutes ces dépendances.

Au fil des ans, j'ai vu le langage C ++ grandir, évoluer et s'adapter au fil du temps. Au début, il est resté presque le même pendant de nombreuses années, mais au cours des 10 dernières années, il a radicalement changé au cours de cette courte période depuis sa création.

Je mentionne tout cela parce que C ++ est l'un des langages les plus difficiles à maîtriser pleinement en raison de sa polyvalence, de sa puissance, de ses nombreuses fonctionnalités et de sa capacité à vous permettre de vous tirer une balle dans le pied! Et même avec toutes ses mises en garde, il s'agit de l'un des langages les plus puissants et préférés qui est utilisé dans le top de l'industrie comme standard pour ce type de développement parce que lorsqu'il est fait correctement, il est rapide, concis, fiable et utilise le plus petite empreinte de pied.

Depuis lors, je suis autodidacte en C / C ++ depuis de nombreuses années avec l'intention et la concentration sur l'apprentissage de la programmation graphique 3D et de la conception du moteur de jeu. J'ai investi de 100 à 1 000 heures de recherche, de recherche et bien plus encore dans la lecture, l'apprentissage et l'application de ces connaissances dans la conception de produits et d'applications de travail utiles. J'ai toujours eu la volonté et le désir de vouloir en savoir plus pour améliorer mes compétences et mon métier.


C'était la première étape, puis j'avais commencé à lire et à travailler avec initialement DirectX 9.c, ce que j'ai fait en C / C ++ et même en C #. Ensuite, je suis passé à DirectX 10 et à Legacy OpenGL 1.0. De leur vient DirectX 11 et OpenGL 3.x - 4.x et maintenant j'ai même essayé Vulkan.

J'ai construit des moteurs de jeu performants à travers différents didacticiels en ligne à la fois au format texte et vidéo. J'ai déjà déclaré que j'avais une solide formation en mathématiques, mais cela se limitait au calcul I et II. J'ai dû m'enseigner le calcul vectoriel dont j'avais quelques connaissances dans mon cours de physique basé sur le calcul à l'université, mais comme pour l'algèbre linéaire avec les transformations affines et la géométrie analytique, j'ai dû les apprendre par moi-même lorsque certaines équations, fonctions, méthodes, algorithmes et des concepts étaient nécessaires. Ensuite, j'ai dû apprendre à les traduire en un code efficace, lisible, fiable et réutilisable qui était générique et sans bogue autant que possible, mettant des centaines à des milliers d'heures de débogage.

Ce fut un merveilleux voyage pour apprendre les sujets et les algorithmes qui incluent la gestion de la mémoire, le comptage des références, l'instanciation, la récursivité et bien plus encore qui sont utilisés dans de nombreux sinon tous les composants d'un moteur de jeu où ils sont vastes. Je pourrais les énumérer tous ici, mais ce serait suffisamment d'informations pour remplir 3 ou 4 espaces de réponses qui méritent d'être écrits. Cependant, je vais inclure la liste des sujets généraux mais pas leurs sous-sujets.

Voici les sujets ou la liste des sujets dans ce qui consiste en un moteur de jeu entièrement fonctionnel qui comprend toutes les diverses techniques de rendu, la configuration des pipelines de rendu et de shader, les techniques d'ombrage et d'éclairage via les shaders, le pré et post-traitement, les tampons de cadre, les tampons de retour , chargement d'image, chargement et analyse audio et de modèle, création de formes primitives avec des propriétés de matériau de couleur, texture et coordonnées normales avec mappage de texture manuel, transformations d'objet, types de caméra, hiérarchies de graphiques de scène, classes de gestionnaire pour les textures, l'audio, les polices et les shaders et gestion de la mémoire, système de journalisation avec gestion des exceptions, techniques de programmation multithread et parallèle, mise en réseau, moteur physique, détection de collision, générateur de particules, animation, IA de jeu, génération de terrain, boîtiers ciel et dômes ciel, rendu d'eau,feuillage et plus ..., des interfaces graphiques avec une police texturée pour le rendu de texte, des superpositions HUD, des inventaires, la génération de cartes et de macros, un système d'état et des machines d'état, et enfin l'écriture d'un analyseur pour créer votre propre langage de script pour automatiser la plupart de ces objets à avoir la possibilité de modifier les valeurs des données dans le moteur sans avoir à recompiler simplement en chargeant dans les fichiers de données pour remplir les objets de données et les structures dans leurs conteneurs respectifs au démarrage de l'application.et enfin écrire un analyseur pour créer votre propre langage de script pour automatiser une grande partie de ces objets pour avoir la possibilité de modifier les valeurs des données dans le moteur sans avoir à recompiler simplement en chargeant dans les fichiers de données pour remplir les objets et les structures de données dans leurs conteneurs respectifs au démarrage de l'application.et enfin écrire un analyseur pour créer votre propre langage de script pour automatiser une grande partie de ces objets pour avoir la possibilité de modifier les valeurs des données dans le moteur sans avoir à recompiler simplement en chargeant dans les fichiers de données pour remplir les objets et les structures de données dans leurs conteneurs respectifs au démarrage de l'application.


Au fil des années, j'ai été intrigué de vouloir apprendre le langage d'assemblage, de leur je voulais en savoir plus sur les compilateurs, les assembleurs et les systèmes d'exploitation simples, je veux dire leur fonctionnement interne, comment ils sont construits et conçus.

Le temps a passé, puis j'ai fait un petit pas et j'ai commencé à apprendre l'émulation matérielle. Je me suis concentré spécifiquement sur la NES mais je voulais apprendre l'émulation matérielle des CPU en général. Cela m'a amené à en apprendre davantage sur le jeu d'instructions dans lequel je connaissais déjà le concept et ce que c'était car j'étais déjà familier avec la famille x86 d'Intel dans une certaine mesure, mais maintenant je devais apprendre le jeu d'instructions 6502.

Pourtant, en plongeant dans ce domaine, j'ai fini par faire plus de recherches et j'ai commencé à en apprendre davantage sur l'architecture du jeu d'instructions du point de vue de l'ingénierie. Cela m'a permis d'apprendre comment le CPU est construit à partir des portes logiques et comment les portes logiques sont construites à partir de transistors avec d'autres composants électriques divers. J'ai donc fini par apprendre à ce sujet sous deux angles: de haut en bas et de bas en haut. Les deux méthodes ont été très efficaces et je pense que l'apprentissage des deux aide à créer ce pont ou cet écart où le logiciel alimente le matériel.

À partir de cela, j'ai dû rafraîchir mon algèbre booléenne et j'ai fini par en apprendre davantage sur K-Maps, les tables d'implication, les machines d'état à la fois Mealy et Moore et diverses autres choses qui relient la logique binaire et l'arithmétique aux portes logiques physiques et aux circuits intégrés. Et cela m'amène au passé de ressentiment où j'ai commencé à travailler avec Logisim, et commencé à apprendre le HDL, le VHDL, Verilog etc ...

J'ai appris tout cela pendant mon temps libre quand je le pouvais au cours des 15 à 18 dernières années.


Voici quelques sites et liens qui m'ont guidé au fil des ans. Beaucoup d'entre eux sont récents, car bon nombre des sites que j'ai appris à l'origine n'existent plus, j'ai perdu leurs liens et je ne m'en souviens pas, ou les moteurs de recherche les ont poussés au fond de leurs listes de recherche ...

  • Langages - C ++

  • Tutoriels graphiques 3D et sites Web de ressources

  • La série et les chaînes Youtube couvrent les sujets ci-dessus ainsi que le génie matériel, informatique et électrique. Il y en a trop pour les énumérer, je vais donc en énumérer quelques-unes ici que je trouve les plus utiles et les plus ingénieuses. Je ne fournirai pas les liens, mais vous pouvez rechercher sur YouTube ces chaînes.

    • 3Blue1Brown - Mathématiques avancées
    • Bisqwit - Programmation C / C ++ avancée (projets d'application) - Emulateur matériel NES
    • Jason Turner - Techniques de programmation C ++ modernes avancées
    • javidx9 - Programmation C / C ++ avancée (projets d'application) - émulateur matériel NES / certains assemblages
    • MIT OpenCourse - Cours collégiaux en mathématiques et informatique
    • Cours en ligne Bilkent - Cours collégiaux en informatique et génie informatique (CPU Design MIPS)
    • The Cherno - Thèmes et applications de programmation C / C ++ avancée - Développement de moteur de jeu
    • Ben Eater - Ingénierie matérielle - Application pratique via des maquettes
    • Neso Academy - Ingénierie matérielle - Théorie et concepts
    • Socratica - Programmation Python
    • En termes simples - Ingénierie matérielle - Théorie et concepts
    • Bitwise - Conception C / C ++ avancée d'un assembleur via une émulation matérielle
    • Bo Qian - C ++ Sujets en structures de données et algorithmes.
    • LineByLine - Programmation Vulkan
    • Joshua Shucker - Programmation Vulkan
    • www.MarekKnows.com - Développement C ++, 3D Math et moteur de jeu

Et ceux-ci ne tiennent pas compte de certains des différents livres que j'ai sur ces sujets.

-Note- S'il vous plaît ne votez pas sur ce point car il ne s'agit que d'un message au lecteur de ma propre expérience personnelle et est dénué de toute tentative de réponse ou de référence à la question d'origine. Dans les prochains jours, quand j'aurai le temps; Je vais ajouter une réponse de suivi pour donner mon avis sur la question du PO tout en fournissant des liens utiles comme référence et un ensemble de ressources et je mettrai également à jour cette réponse pour inclure quelques liens ici et pour modifier cette note. Il est tard et je n'ai actuellement pas le temps de relire et d'éditer ce que j'ai déjà écrit. Je ferai ça quand je pourrai ".


Je viens de mettre à jour cette réponse ou ce message. J'allais ajouter la 2e partie qui répondra réellement à la question, mais je n'ai pas assez de points de réputation pour le faire. Il me faudra un certain temps pour accumuler les points de réputation nécessaires avant de pouvoir ajouter ma deuxième réponse. Ce message n'est pas la réponse réelle, mais je vais l'utiliser comme référence et rechercher un tableau dans le raisonnement de ma vraie réponse. Il est nécessaire d'avoir certaines des ressources répertoriées ci-dessus pour aider à combler l'écart entre le logiciel et le matériel.
Francis Cugler

-2

Au fond, un CPU n'est généralement qu'une machine à états. Vous devrez donc comprendre comment les portes logiques et les bascules ou les registres se combinent pour créer des machines à états.

Une machine à états prend les entrées et l'état actuel, les exécute via une logique booléenne (et potentiellement arithmétique), puis fournit des sorties et un état suivant. L'une des entrées peut être le registre d'instructions. L'une des sorties peut être une validation et une sélection de la source pour recharger le registre d'instructions, peut-être aussi incrémenter ou charger un autre registre agissant comme compteur de programme. Avec cela, plus une mémoire adressable, vous pouvez séquencer les instructions.

Une fois que vous avez un moyen de séquencer les instructions, vous pouvez utiliser la logique pour décoder ces bits d'instructions, plus l'état actuel, en un autre groupe de bits de contrôle. Certains de ces bits de contrôle peuvent agir comme des entrées pour contrôler un tas de logique qui peut faire de la logique arithmétique et à l'échelle du mot, appelez-le une ALU. D'autres bits peuvent charger des éléments ou sélectionner des entrées pour l'ALU. D'autres bits peuvent indiquer où stocker les résultats de l'ALU. Ou chargez des registres d'adressage. Ou écrivez dans la mémoire ou sur d'autres sorties. Etc.

Une partie de la conception d'un jeu d'instructions consiste simplement à déterminer quelles combinaisons de bits, une fois décodées, contrôlent tous les registres et le séquençage de la machine d'état. Cela avait été fait et (ré) optimisé des milliers de façons différentes.

Il existe au moins 3 niveaux de manuels universitaires sur ce sujet non trivial.


2
Cela n'explique pas comment l'opération MOV est convertie en valeur binaire. Cela ne mentionne pas que l'instruction MOV est une valeur, c'est un mot-clé que nous utilisons, nous n'avons donc pas à mémoriser une valeur binaire de 16 à 32 bits.
Ramhound
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.