-1
votes

Pourquoi les instructions 16 bits ne peuvent-elles pas accéder aux registres hauts des registres à usage général

Donc, en ce moment, j'ai lu le livre "Guide définitif sur ARM Cortex-M3 / M4" et je ne peux pas comprendre pourquoi les instructions 16 bits ne peuvent pas accéder aux registres à usage général élevé R8-R12.

Il dit que très peu d'entre eux peuvent accéder à ces registres, mais généralement pas.


3 commentaires

Si vos instructions ne font que 16 bits, il est possible de coder 2-3 registres d'opérande avec des champs de sélecteur de registre à 3 bits, mais le codage de 2-3 registres d'opérande avec des champs de sélecteur de registre à 4 bits ne l'est pas.


Garder les choses compactes en rendant les opcodes plus petits est la façon dont le code Thumb peut améliorer les performances, en particulier sur les machines limitées par bus.


avant de lire un livre comme celui-là, vous avez besoin du guide définitif sur le bras (n'importe quoi) qui est le manuel de référence architecturale et le manuel de référence technique pour le noyau en question (armv7-m pour les deux) et vous pouvez facilement voir l'encodage pour les instructions n'ont pas de place pour 4 bits par registre.


3 Réponses :


5
votes

16 bits signifie que l'instruction de code machine n'a que 16 bits pour coder les informations. 8 registres prennent 3 bits à encoder. 12 registres ont besoin de 4 bits pour encoder. Ensuite, nous avons besoin d'espace pour les opcodes et autres options, ce qui signifie que le bit supplémentaire peut être un peu trop.


4 commentaires

Et cela suppose une instruction à registre unique telle que la constante de charge. Cela ne fait qu'empirer pour des choses comme l'arithmétique.


Pourquoi 8 registres prennent-ils 3 bits à encoder? Les registres sont tous 32 bits. Ne jugez pas trop fort, je viens de commencer à apprendre l'architecture


@ SL7Bot: Vous devez attribuer un motif binaire unique à chaque registre, afin que le décodeur d'instructions sache de quel registre vous parlez. Pour 8 modèles de bits uniques, vous avez besoin d'au moins log_2 (8) = 3 bits. "Attribuer un motif binaire unique" revient bien entendu à donner à chaque registre une adresse numérique et à coder ce nombre en binaire. Encore une fois: pour encoder les nombres 0-7, vous avez besoin de 3 bits.


Merci c'est ce que j'ai pensé. Maintenant, je comprends



5
votes

Le codage de l'adresse de 8 registres prend 3 bits. Le codage de l'adresse de 12 registres prend 4 bits.

Si vous avez une instruction à 3 registres, vous auriez besoin de 12 bits pour coder les 3 registres, ce qui ne laisse que 4 bits pour l'instruction. Vous ne pouviez avoir qu'un maximum de 16 instructions.


2 commentaires

vous pouvez toujours avoir un ou plusieurs de ces 16 motifs pour avoir un tas de sous-motifs qui n'utilisent pas trois registres. assez courant en particulier pour le bras ...


Les instructions au pouce sont principalement à 2 opérandes (comme x ^= y au lieu de z = x ^ y que les instructions utilisent en mode ARM), à l'exception de quelques instructions très courantes comme adds reg, reg, reg qui peuvent utiliser 3 registres différents dans un Instruction 16 bits. Mais oui, sauvegarder des bits sur les numéros de registre est toujours critique.



1
votes

Les seuls guides définitifs sur ces noyaux sont la documentation du bras. Avant de lire quoi que ce soit d'autre ou d'apprendre un jeu d'instructions, vous devez avoir la documentation; dans ce cas, ARM Architectural Reference Manual pour l'ARMV7-m ainsi que le manuel de référence technique cortex-m3 ou cortex-m4. Si votre livre fait une telle déclaration et ne l'explique pas, c'est loin d'être définitif.

C'est techniquement possible mais cela prendrait beaucoup de place et peut-être irait à l'encontre du but de tenter des instructions 16 bits (cela ne veut pas dire un processeur ou des registres 16 bits ou quoi que ce soit du genre, les instructions elles-mêmes sont 16 bits). Si vous regardez le code compilé et comment les compilateurs fonctionnent, une grande partie du code généré utilise des registres inférieurs ou peut être créé comme tel. Il s'agit donc d'un compromis entre la richesse du jeu d'instructions et le nombre d'instructions, ce qui est vrai indépendamment du nombre de registres dont vous disposez.

La taille du registre n'a pas d'importance, le nombre de registres est ce qui compte. Pour par exemple

.thumb
mov r1,r2
mov r10,r2
mov r1,r11
mov r10,r11
    
00000000 <.text>:
   0:   1c11        adds    r1, r2, #0
   2:   4692        mov r10, r2
   4:   4659        mov r1, r11
   6:   46da        mov r10, r11

Vous devez quelque part encoder quel registre est quel. Le commentaire est bien sûr spécifique aux anciennes / originales instructions 16 bits et non aux extensions thumb2.

Vous avez donc besoin d'un modèle, naturellement on:

0001100mmmnnnddd

Si vous vous limitez à 8 registres, vous n'avez besoin que de trois bits par registre pour décrire quel registre est utilisé pour chaque champ.

Si vous souhaitez utiliser 16 registres dans vos instructions, vous avez besoin de 4 bits:

00xxxx shift, add, subtract, move, and compare
010000 data processing instructions
010001 special data
01001x ...

Si vous voulez 32 registres dans votre jeu d'instructions (généralement pas le pouce ARM), alors cinq bits:

2 to the power 0 is 1
2 to the power 1 is 2
2 to the power 2 is 4
2 to the power 3 is 8
2 to the power 4 is 16
2 to the power 5 is 32
2 to the power 16 is 65536

Remarque

00000 r0
00001 r1
10000 r16
11111 r31

etc.

Si vous voulez décrire 8 choses, il faut 3 bits si vous voulez décrire 16 choses, cela prend 4 bits.

16 bits signifie potentiellement 65536 instructions uniques. Le document d'ARM fait un bon travail en montrant comment il dispose ses jeux d'instructions, il tend vers la maximisation du nombre et des fonctionnalités possibles des instructions par rapport à MIPS, qui tend vers la simplicité de la logique de décodage d'abord, puis les fonctionnalités ensuite (compromis de conception).

Sauter en avant par exemple, les 6 premiers bits de l'instruction sont l'opcode

0000 r0
0001 r1
0010 r2
....
0111 r7
1000 r8
1001 r9
....
1110 r14
1111 r15

etc. Montré de différentes manières en fonction de l'ARM ARM que vous téléchargez.

Ils n'ont pas eu à mettre en œuvre trois instructions de registre, mais ils ont choisi de le faire. Si ces instructions avaient pris en charge r0 à r15 pour chaque opérande, cela signifie que 12 bits sont nécessaires et qu'il reste quatre bits pour le codage, y compris un ou plusieurs d'entre eux pour indiquer cette classe d'instructions et le reste quel opérande, vous effaceriez probablement au moins un la moitié des instructions possibles (un bit dédié à l'indication est-ce une instruction à trois registres ou non) laissant 7 opérations possibles ou, un quart de l'espace d'instructions (deux bits) laissant 2 bits pour choisir l'opérande le rendant peu riche en fonctionnalités . Au lieu de cela, ce qu'ils ont réellement fait est de prendre 1 / 4ème de l'espace d'instructions mais de laisser au moins 5 bits pour l'opérande et / ou d'autres fonctionnalités (immédiates, etc.).

Le codage T1 pour add est donc

000 r0
001 r1
010 r2
011 r3
100 r4
101 r5
110 r6
111 r7

Les deux premiers bits indiquent de quel groupe d'instructions il s'agit, si vous regardez, vous verrez que le bit 10 indique immédiatement ou enregistrez les bits mmm sont un registre ou un immédiat entre 0 et 7, il y a beaucoup de fois qu'un programmeur veut incrémenter de 1 ou 2 ou un petit nombre et devoir forcer une instruction et graver un registre pour mettre ce petit nombre contre le compromis de brûler un espace d'instruction est un équilibre ici.

Quoi qu'il en soit, vous voyez ici qu'il y a trois bits pour les registres rm, rn et rd pour l'encodage de cette instruction. (ajoutez rd, rn, rm) et cela indique que r0-r7 est possible pour n'importe lequel de ces champs.

Pour le rendre plus complet, il existe une instruction de registre mov high qui vous permet de déplacer haut / bas, bas / haut ou haut / haut, techniquement bas / bas, mais ils préfèrent que vous utilisiez un encodage différent comme documenté. L'un de ceux-ci peut être ajouté rd, rn, # 0 lié aux trois registres ci-dessus. Et c'est ce que vous voyez l'assembleur gnu faire

add r1,r2,r3

Le fait qu'il existe un moyen de se déplacer vers et depuis les registres hauts, c'est plus rapide que vers / depuis la pile (pas de cycle de mémoire) afin que le compilateur puisse toujours choisir d'utiliser un / certains registres hauts (comprenant que push / pop est limité à pour des raisons évidentes (lire la documentation) donc il y a un coût pour les conserver et les restaurer, c'est un compromis).

Vous devez donc vous en tenir au véritable guide définitif de quelque chose plutôt que de quelque chose qui prétend être.

La seule chose que vous ne trouverez presque jamais nulle part à moins que vous ne vous trouviez dans le cerveau / le cube / le bureau / la salle de conférence à ce (s) moment (s) le (s) concepteur (s) a mis en œuvre le jeu d'instructions ou une instruction particulière est le "pourquoi" fais le. (pourquoi pas de trois registres et, xor, etc.) Donc malgré les autres réponses, commentaires et ce qui précède, c'est parce qu'ils le voulaient. Et si vous avez besoin d'en savoir plus, vous pouvez peut-être trouver un emploi à bras le corps et peut-être qu'ils sont toujours là et pourraient passer du temps avec vous, mais je m'attends à ce qu'ils soient à la retraite.

Et cela fait si longtemps que la réponse des parties concernées varierait probablement quant à savoir qui a dit quoi et quand il y a toutes ces années. Mais lorsque vous essayez de prendre un jeu d'instructions 32 bits et de mapper un sous-ensemble d'instructions 16 bits pour doubler le nombre d'instructions par unité d'espace, tout en essayant d'être suffisamment riche pour ne pas augmenter considérablement le nombre d'instructions par tâche, limitant la plupart des instructions aux registres généraux inférieurs pour une architecture comme celle-ci semble être un choix de conception évident. Je devrais revoir l'équivalent MIPS du pouce pour voir ce qu'ils ont fait, je m'attendrais à ce qu'ils aient fait la même chose. De même, je devrais également revoir risc-v et tout autre qui a fait la même chose.

Comprenez qu'il s'agissait d'un choix de conception et non d'une exigence.


0 commentaires