web-dev-qa-db-fra.com

Conversion très simple ARM en binaire / hexadécimal

J'ai essayé d'utiliser cette page ainsi que divers autres guides pour comprendre comment exprimer très simplement ARM instructions binaires et hexadécimales. Il semble que cela devrait être un processus simple pour moi, mais je ne comprends toujours pas. Voici quelques exemples.

NOP de base:

       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 enregistrer la valeur:

add r0, #0x1a

Tous ces didacticiels en ligne sont excellents pour décrire comment utiliser des instructions comme celles-ci, mais aucun que j'ai pu trouver ne montre comment convertir une instruction ARM en code binaire/hex/machine dans lequel elle obtient assemblé.

Merci d'avance pour votre aide.

24
n00neimp0rtant

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

ARM data processing instructions

Vous avez un tableau des codes de condition sur cette page. Les registres sont codés 0000 par 1111.

Tous vos exemples entrent dans la même catégorie. L'image est extraite d'un document sur mon disque dur, mais j'ai également réussi à la 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

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

32
Roman Saveljev

Tout d'abord, vous avez besoin du ARM Architectural Reference Manual (ARM ARM) sur infocenter.arm.com, des manuels de référence, obtenez le plus ancien (armv5 ou autre). Le jeu d'instructions est bien défini dans Là.

Deuxièmement, pourquoi ne rassemblez-vous pas seulement quelques instructions et voyez ce qui se passe?

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

quel que soit l'assembleur croisé que vous avez (voir http://github.com/dwelch67/raspberrypi dans le répertoire build gcc pour un script, exécutez simplement à travers binutils dans ce 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-elf vs arm-elf, etc. peu importe pour cela, tous font 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 d'armement complet de 32 bits (pas le pouce) sont le code de condition, voir la section du champ de condition dans le ARM ARM. Un 0xE signifie toujours, toujours exécuter cette instruction. 0b0000 est eq s'exécute uniquement si le drapeau z est défini, 0b0001 ne s'exécute que si z est effacé, etc.

Dans le ARM ARM Poussez dans le jeu d'instructions arm, puis la liste alphabétique des instructions arm, puis trouvez 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 zéro bits 15:12 sont zéro les bits 27:26 sont zéro et 24:21 sont 1010 c'est donc une instruction cmp

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

nous savons que nous voulons que le deuxième opérande soit simplement un registre, qui est appelé opérandes de traitement des 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 de l'instruction cmp qu'il est dit que 15:12 devrait être nul, je me demande si cela se soucie, un cmp ne stocke pas de résultat dans un registre donc rd n'est pas utilisé. rm est utilisé et dans ce cas, nous voulons r0, donc 0b0000 va en 3: 0, notez également qu'il montre les bits 27:25 sous forme de zéros, dans l'instruction cmp 25 est I, nous savons maintenant que nous voulons un zéro là, donc

entre la page cmp et ce traitement des données - page d'inscription nous avons toute l'image

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

l'ajout est similaire mais utilise un immédiat, alors allez à l'instruction add dans la liste alpha des instructions. nous savons maintenant du cmp que 24:21 pour cette classe d'instruction est l'opcode, nous pouvons à peu près aller directement à l'opérande shifter pour continuer à partir de là

cette fois, nous faisons ajouter rd, rn, # immediate

alors cherchez la page pour #immediate

et l'encodage est

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 façons différentes. les bits 7: 0 sont immédiats et les bits 11: 8 permettent de faire tourner cet immédiat, 26 est 0x1A, nous pourrions simplement mettre 0x1A dans les 8 bits inférieurs et régler la rotation sur 0, et c'est ce que l'assembleur gnu a fait. pourrait probablement mettre un 0x68 dans les 8 bits inférieurs et un 1 dans le champ rotation_imm 1101000 tourné à droite 1 * 2 bits est 11010 = 0x1A = 26.

10
old_timer

Vous devriez obtenir une copie du ARM ARM 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 de manière conditionnelle, utilisez simplement la pseudo-condition AL (1110).

Le premier registre (Rn) dans le codage n'est pas utilisé pour l'instruction MOV et doit être défini sur 0000 comme défini par l'ARM ARM).

Le deuxième registre est la destination, ici vous encodez simplement le numéro de registre, donc dans votre cas ce serait aussi 0000 parce que vous utilisez r0 comme destination, pour r4 ce serait 0100.

Le reste est l'opérande dit de décalage qui est très flexible. Ce pourrait être un simple registre comme dans votre cas (r0) alors c'est juste 0000 0000 0000 où les 4 derniers bits encodent à nouveau le registre. Il peut également coder différents types de décalages et tourner avec des valeurs de registre ou immédiates pour le traitement des données.

Mais il pourrait également s'agir d'un immédiat où 8 bits sont codé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 également égal à 1, dans tous les autres cas, il sera égal à 0.

6
Nico Erfurth