J'ai moi-même écrit quelques-uns (assembleurs et désassembleurs) et je ne voudrais pas commencer par x86. Si vous connaissez x86 ou tout autre jeu d'instructions, vous pouvez récupérer et apprendre rapidement la syntaxe d'un autre jeu d'instructions (une soirée/après-midi), au moins la part des lions.Le fait d'écrire un assembleur (ou un désassembleur) vous apprendra certainement un ensemble d'instructions, et vous saurez que l'ensemble d'instructions est meilleur que de nombreux programmeurs chevronnés pour cet ensemble d'instructions qui n'ont pas examiné le microcode à ce niveau. msp430, pdp11, et le pouce (pas les extensions thumb2) (ou mips ou openrisc) sont tous de bons endroits pour commencer, pas beaucoup d'instructions, pas trop compliqué, etc.
Je recommande d'abord un désassembleur, et avec cela un Si ce n'est pas le cas, utilisez au moins un désassembleur (choisissez certainement un jeu d'instructions pour lequel vous avez déjà un assembleur, un éditeur de liens et un désassembleur) et avec un crayon et du papier, comprenez la relation entre le code machine et l'assemblage, en particulier les branches, ils ont généralement une ou plusieurs bizarreries comme le compteur de programme est une instruction ou deux en avant lorsque le décalage est ajouté, pour gagner un autre bit qu'ils mesurent parfois en instructions entières et non en octets.
Il est assez facile de force brute analyser le texte avec un programme C pour lire les instructions. Une tâche plus difficile mais peut-être aussi éducative serait d'utiliser bison/flex et d'apprendre ce langage de programmation pour permettre à ces outils de créer un analyseur syntaxique encore plus extrême qui s'interface alors avec votre code pour vous dire ce qui a été trouvé.
L'assembleur lui-même est assez simple, il suffit de lire les caractères ASCII et de définir les bits dans le code machine. Les branchements et autres instructions relatives aux pc sont un peu plus douloureux car ils peuvent prendre plusieurs passages à travers la source/les tables pour les résoudre complètement.
mov r0,r1
mov r2 ,#1
l'assembleur commence l'analyse du texte pour une ligne (étant définie comme les octets qui suivent un flux 0xA retour chariot 0xD ou ligne), jeter l'espace blanc (espaces et onglets) jusqu'à ce que vous obtenez à quelque chose non blanc espace, puis strncmp qu'avec les mnémoniques connus. si vous en frappez un, alors analysez les combinaisons possibles de cette instruction, dans le cas simple ci-dessus après le saut de l'espace blanc vers un espace non-blanc, peut-être que la première chose que vous trouverez doit être un registre, puis un espace blanc virgule. Enlevez les espaces et les virgules et comparez-les à une table de chaînes ou passez-la à l'analyse. Une fois que ce registre est fait, passez la case où la virgule est trouvée et disons que c'est soit un autre registre, soit un immédiat. Si immédiat, disons qu'il doit avoir un signe #, si le registre indique qu'il doit commencer par un 'r' minuscule ou majuscule. après l'analyse de ce registre ou immédiatement, alors assurez-vous qu'il n'y a rien d'autre sur la ligne qui ne devrait pas être sur la ligne. Construire le code machine pour cette instruction ou au moins autant que possible, et passer à la ligne suivante. Il peut être fastidieux, mais il est difficile de ne pas analyser ascii ...
au minimum, vous voulez une table/tableau qui accumule le code machine/données est créé, plus une méthode pour obtenir des instructions de marquage comme étant incomplet , les instructions pc-relatives à compléter sur une future passe. vous voudrez également une table/tableau qui recueille les étiquettes que vous trouvez et l'adresse/décalage dans la table de code machine où trouvé. Ainsi que les étiquettes utilisées dans l'instruction comme une destination/source et le décalage dans la table/tableau contenant l'instruction partiellement complète qu'ils vont avec. après le premier passage, retournez dans ces tables jusqu'à ce que vous ayez fait correspondre toutes les définitions d'étiquette avec les étiquettes utilisées comme source ou destination, en utilisant l'adresse/l'offset de définition d'étiquette pour calculer la distance à l'instruction en question et terminez la création le code machine pour cette instruction. (un démontage peut être nécessaire et/ou utiliser une autre méthode pour se souvenir du type d'encodage lorsque vous y reviendrez plus tard pour terminer la construction du code machine).
L'étape suivante consiste à autoriser plusieurs fichiers sources, si c'est quelque chose que vous voulez autoriser. Maintenant vous devez avoir des étiquettes qui ne sont pas résolues par l'assembleur, vous devez donc laisser des espaces réservés dans la sortie et faire la plus longue des instructions de saut/branchement parce que vous ne savez pas à quelle distance se trouvera la destination.Ensuite, il y a le format de fichier de sortie que vous choisissez de créer/utiliser, puis il y a le lieur qui est pour la plupart simple, mais vous devez vous rappeler de remplir le code machine pour les instructions relatives au pc final, pas plus dur que dans l'assembleur lui-même. Remarque, l'écriture d'un assembleur n'est pas nécessairement liée à la création d'un langage de programmation, puis l'écriture d'un compilateur pour lui, chose distincte, différents problèmes. En fait, si vous voulez créer un nouveau langage de programmation, utilisez simplement un assembleur existant pour un jeu d'instructions existant. Non requis bien sûr, mais la plupart des enseignements et des tutoriels vont utiliser l'approche bison/flex pour les langages de programmation, et il existe de nombreuses notes de cours/ressources pour commencer les classes de compilateur que vous pouvez utiliser pour commencer, puis modifier le script pour ajouter les fonctionnalités de votre langue. Le milieu et le dos sont le plus grand défi que l'extrémité avant. Il existe de nombreux livres sur ce sujet et de nombreuses ressources en ligne. Comme mentionné dans une autre réponse llvm n'est pas un mauvais endroit pour créer un nouveau langage de programmation le milieu et les backends sont faits pour vous, vous avez seulement besoin de se concentrer sur le langage de programmation lui-même, le frontal.
Quelque chose à penser: Automate fini pour vérifier si l'utilisateur utilise même les instructions appropriées, et vous aurez également besoin d'un analyseur pour vous assurer que ce que le programmeur écrit est correct. Bien qu'il y ait beaucoup de choses sur le système, vous devrez vous inquiéter, il y a aussi beaucoup de théorie de calcul que vous devrez également connaître. –
Peut-être que vous devriez étudier un paquet comme [NASM] (http://www.nasm.us/). –
vérifier [ce défi sur le golf de code] (http://codegolf.stackexchange.com/questions/4732/emulate-an-intel-8086-cpu) pour les ressources 8086 et un exemple de programme pas trop court en utilisant un sous-ensemble de 8086 dans les deux formes source et binaire. OMI, le Manuel de 1979 est le point de départ. ... Jetez aussi un coup d'œil à [la question de mon wiki sur les ressources de l'assemblée] (http://stackoverflow.com/a/7203667/), en particulier le fichier "PDP-1_Macro.pdf" qui donne une description détaillée d'un assembleur très primitif . –