Pourquoi le registre PC ARM pointe-t-il vers l'instruction après la suivante à exécuter?
Selon le bras IC.
Dans L'état ARM, la valeur du PC est l'adresse de l'instruction en cours plus 8 octets.
Dans L'État du pouce:
- pour les instructions B, BL, CBNZ et CBZ, la valeur du PC est l'adresse de l'instruction courante plus 4 octets.
- pour toutes les autres instructions qui utilisent des étiquettes, la valeur du PC est l'adresse de l'instruction en cours plus 4 octets, avec le bit [1] du résultat effacé à 0 pour le rendre mot-alignés.
En disant simplement, la valeur du registre PC pointe vers l'instruction après l'instruction suivante. C'est la chose que je ne comprends pas. Habituellement (en particulier sur le registre de compteur de programme x86) est utilisé pour pointer vers l'adresse de l'instruction suivante à exécuter.
Alors, quels sont les prémisses qui sous-tendent cela? Exécution conditionnelle, peut-être?
2 réponses
C'est un peu méchant de fuite d'abstraction héritée.
La conception ARM originale avait un pipeline à 3 étages (fetch-decode-execute). Pour simplifier la conception, ils ont choisi de faire lire le PC comme la valeur actuellement sur les lignes d'adresse d'extraction d'instruction, plutôt que celle de l'instruction en cours d'exécution d'il y a 2 cycles. Puisque la plupart des adresses relatives au PC sont calculées au moment de la liaison, il est plus facile d'avoir l'assembleur / éditeur de liens compenser ce décalage de 2 instructions que de concevoir toutes les logique pour "corriger" le registre du PC.
Bien sûr, c'est tout fermement sur les "choses qui fait sens il y a 30 ans" tas. Maintenant, imaginez ce qu'il faut pour garder une valeur significative dans ce registre sur la scène 15+ d'aujourd'hui, les pipelines à problèmes multiples et hors service, et vous comprendrez peut-être pourquoi il est difficile de trouver un concepteur de CPU ces jours-ci qui pense exposer le PC en tant que Registre est une bonne idée.
Pourtant, à la hausse, au moins ce n'est pas aussi horrible que slots de retard. Plutôt, contrairement à ce que vous supposez, l'exécution conditionnelle de chaque instruction n'était vraiment qu'une autre optimisation autour de ce décalage de pré-lecture. Plutôt que de toujours avoir à prendre des retards de vidange de pipeline lors de la ramification autour du code conditionnel (ou en exécutant toujours ce qui reste dans le tuyau comme une personne folle), vous pouvez éviter complètement les branches très courtes; le pipeline reste occupé, et les instructions décodées peuvent simplement s'exécuter comme NOPs lorsque les drapeaux ne correspondent pas*. Encore une fois, ces jours, nous avons prédicteurs de branche efficaces et cela finit par être plus un obstacle qu'une aide, mais pour 1985 c'était cool.
* "...le jeu d'instructions avec le plus de NOPs sur la planète."
C'est vrai...
Un exemple est ci-dessous: Programme C:
int f,g,y;//global variables
int sum(int a, int b){
return (a+b);
}
int main(void){
f = 2;
g = 3;
y = sum(f, g);
return y;
}
Compiler en assembly:
00008390 <sum>:
int sum(int a, int b) {
return (a + b);
}
8390: e0800001 add r0, r0, r1
8394: e12fff1e bx lr
00008398 <main>:
int f, g, y; // global variables
int sum(int a, int b);
int main(void) {
8398: e92d4008 push {r3, lr}
f = 2;
839c: e3a00002 mov r0, #2
83a0: e59f301c ldr r3, [pc, #28] ; 83c4 <main+0x2c>
83a4: e5830000 str r0, [r3]
g = 3;
83a8: e3a01003 mov r1, #3
83ac: e59f3014 ldr r3, [pc, #20] ; 83c8 <main+0x30>
83b0: e5831000 str r1, [r3]
y = sum(f,g);
83b4: ebfffff5 bl 8390 <sum>
83b8: e59f300c ldr r3, [pc, #12] ; 83cc <main+0x34>
83bc: e5830000 str r0, [r3]
return y;
}
83c0: e8bd8008 pop {r3, pc}
83c4: 00010570 .word 0x00010570
83c8: 00010574 .word 0x00010574
83cc: 00010578 .word 0x00010578
Voir la valeur PC de LDR ci-dessus-ici est utilisé pour charger l'adresse de la variable F,g,y à r3.
83a0: e59f301c ldr r3, [pc, #28];83c4 main+0x2c
PC=0x83c4-28=0x83a8-0x1C = 0x83a8
La valeur du PC est juste l'instruction suivante de l'instruction d'exécution en cours. comme ARM utilise l'instruction 32bits, mais il utilise l'adresse d'octet, donc + 8 signifie 8bytes, la longueur de deux instructions.
, Donc BRAS archi 5 étape pipe linefetch, décodage, exécution, de mémoire, réécriture
Le pipeline à 5 étages du bras
Le registre PC est ajouté par 4 chaque horloge, donc lorsque l'instruction bouillonne pour exécuter-l'instruction en cours, l'horloge PC register est déjà passée à 2! maintenant c'est + 8. cela signifie en fait: PC pointe l'instruction "fetch", l'instruction actuelle signifie" execute " instruction, donc PC signifie le suivant à exécuter.
BTW: le pic est tiré du livre de Harris de la conception numérique et de L'Architecture informatique ARM Edition