Conversion d'instructions de bras très simples en binaire / hex

j'ai essayé d'utiliser cette page ainsi que divers autres guides pour comprendre comment exprimer des instructions de bras très simples comme binaire et hex. Il semble que ce devrait être un processus simple pour moi, mais je ne comprends toujours pas. Voici quelques exemples.

Basic NOP:

       what goes here?          what goes here?
             _↓_                  _____↓____
            |   |                |          |
mov r0, r0 ; ????00?1101?????????????????????
                         |__||__|
                          ↑    ↑
                 how do I express registers?

même question de base pour les autres.

Comparaison de deux registres:

cmp r1, r0

Ajout immédiat pour vous inscrire valeur:

add r0, #0x1a

tous ces tutoriels en ligne sont excellents pour décrire comment utiliser des instructions comme celles-ci, mais aucun Je n'ai été en mesure de trouver réellement marcher à travers la façon de convertir une instruction de bras dans le code binaire/hex/machine dans laquelle il est assemblé.

Merci d'avance pour votre aide.

22
demandé sur n00neimp0rtant 2012-08-03 01:20:28

3 réponses

Voici comment les instructions de traitement des données sont codées:

ARM data processing instructions

vous avez la table des codes d'état dans votre page. Les registres sont codés 00001111.

tous vos exemples appartiennent à la même catégorie. L'image est extraite d'un document sur mon disque dur, mais j'ai aussi réussi à trouver par google. Coder ces instructions est un travail fastidieux.

Donc, mov r0, r0 devrait aller comme ceci:

1110 00 0 0 1101 0000 0000 00000000

j'ai mis Rn à 0, car il n'est pas réellement applicable à MOV. Dans le cas de CMP, je crois, S est toujours 1.

31
répondu Roman Saveljev 2012-08-02 22:10:16

tout d'abord, vous avez besoin du manuel de référence architecturale du bras (ARM ARM) à infocenter.arm.com, manuels de référence, obtenir le plus ancien (armv5 ou autre). le jeu d'instructions est bien défini.

deuxièmement, pourquoi ne pas simplement assembler quelques instructions et voir ce qui se passe?

;@test.s
cmp r1, r0
add r0, #0x1a

whatever cross assembler you have (see http://github.com/dwelch67/raspberrypi dans le répertoire build gcc pour un script, il suffit de lancer les binutils dans ce le script)

arm-none-linux-gnueabi-as test.s  -o test.o
arm-none-linux-gnueabi-objdump -D test.o

arm-none-linux-gnueabi vs arm-none-elfe vs arm-elf, etc n'ont pas d'importance pour ce faire, tous faire la même chose

Disassembly of section .text:

00000000 <.text>:
   0:   e1510000    cmp r1, r0
   4:   e280001a    add r0, r0, #26

les quatre bits supérieurs d'une instruction de bras 32 bits (pas le pouce) sont le code de condition, Voir la section champ de condition dans le bras de bras. un 0xE signifie Toujours, Toujours exécuter cette instruction. 0b0000 est eq ne s'exécutera que si le z drapeau est réglé, 0b0001 ne s'exécutent seulement si z est clair, etc.

dans le bras bras pousser dans l'instruction bras définir, puis la liste alphabétique des instructions de bras, puis trouver cmp il commence par cond 00I10101 rn SBZ shifter

D'après notre instruction cmp ci-dessus, nous voyons 1110 000101010001 ... donc je suis un ZERO bits 15: 12 sont des zero bits 27:26 sont des zero et 24: 21 sont des 1010 donc ceci est une instruction cmp

bits 19 à 16 ci-dessus sont 0b001 qui est rn ainsi = 1 (r1) pour l'opérande shifter dans le bras il vous dit de regarder à L'adressage des opérandes de traitement de données de Mode 1 et a un lien dans le pdf à la page

nous savons que nous voulons que le second opérande soit simplement un registre, qui est appelé opérandes de traitement de données-registre, et un numéro de page, allez à cette page sur cette page 15:12 est rd 11:4 sont des zéros et 3:0 est rm. nous savons d'après l'instruction cmp que 15: 12 devrait être zéro, je me demande s'il s'en soucie, un cmp ne stocke pas un résultat dans un registre donc rd n'est pas utilisé. rm est utilisé et dans ce cas nous voulons r0, donc 0b0000 va dans 3: 0 aussi noter qu'il montre bits 27:25 comme zéros, dans le cmp l'instruction de 25 est je, nous savons maintenant que nous voulons un zéro, donc

entre la page cmp et cette page de traitement des données - registre, nous avons le tableau complet

1110 condition
000 
1010 opcode
1 S (store flags, that is a 1 for a cmp to be useful)
0001 rn
0000 rd/dont care/sbz
00000
000
0000 rm

cmp rn,rm
cmp r1,r0

le complément est similaire, mais utilise un immédiat, donc aller pour le complément d'instruction dans l'alpha de la liste d'instructions. nous savons maintenant de la cmp que 24: 21 pour cette classe d'instruction est le opcode, nous pouvons assez bien aller directement à l'opération shifter pour continuer de là

cette fois, nous sommes l'ajout de rd,rn,#immédiate

alors cherchez la page pour #immediate

et l'encodage

1110 condition, always
001 (note the immediate bit is set)
0100 (opcode for add for this type of instruction)
0 (S not saving the flags, it would be adds r0,r0,#26 for that)
0000 (rn = r0)
0000 (rd = r0)

vient maintenant la partie intéressante, nous pouvons coder les 26 différentes façons. les bits 7: 0 sont les immédiats et les bits 11: 8 permettent que l'immédiat tourne, 26 est 0x1A, on pourrait simplement mettre 0x1A dans les 8 bits inférieurs et régler la rotation à 0, et c'est ce que gnu assembler a fait. pourrait probablement mettre un 0x68 dans les 8 bits inférieurs et un 1 dans le champ rotate_imm 1101000 tourner à droite 1 * 2 bits est 11010 = 0x1A = 26.

10
répondu old_timer 2012-08-02 22:25:44

vous devriez obtenir une copie du bras de bras il décrit l'encodage pour toutes les instructions.

la plupart des instructions ARM utilisent les 4 bits supérieurs pour un code conditionnel. Si vous ne voulez pas exécuter l'instruction conditionnellement, utilisez simplement la pseudo-condition AL (1110).

le premier registre (Rn) dans l'encodage n'est pas utilisé pour L'instruction MOV-et il doit être réglé à 0000 tel que défini par le bras ARM.

le second registre est la destination, ici vous venez encodez le numéro de registre, donc dans votre cas il serait aussi 0000 parce que vous utilisez r0 comme un destinal, pour r4 il serait 0100.

Le reste est le levier de vitesses opérande qui est très flexible. Il peut s'agir d'un simple Registre comme dans votre cas (r0) puis il est juste 0000 0000 0000 où les 4 derniers bits encodent à nouveau le registre. Il peut aussi encoder différents types de déplacements et tourner avec des valeurs de registre ou immédiates pour le traitement des données.

mais cela pourrait aussi être un immédiat où 8 bits sont encodés dans les bits inférieurs et les 4 premiers bits définissent une rotation à droite par Pas de 2 bits. Dans ce cas bit25 sera aussi 1, dans tous les autres cas il est 0.

6
répondu Nico Erfurth 2012-08-02 22:06:04