¿Por qué el registro ARM PC apunta a la instrucción después de la siguiente a ser ejecutada?


Según el CI del BRAZO.

En estado ARM, el valor del PC es la dirección de la instrucción actual más 8 bytes.

En estado pulgar:

  • Para las instrucciones B, BL, CBNZ y CBZ, el valor del PC es la dirección de la instrucción actual más 4 bytes.
  • Para todas las demás instrucciones que usan etiquetas, el valor de la PC es la dirección de la instrucción actual más 4 bytes, con bit[1] del resultado borrado a 0 para hacerlo alineado con palabras.

Simplemente diciendo, el valor del registro PC apunta a la instrucción después de la siguiente instrucción. Esto es lo que no entiendo. Usualmente (particularmente en el x86) el registro de contador de programa se usa para apuntar a la dirección de la siguiente instrucción a ser ejecutada.

Entonces, ¿cuáles son las premisas subyacentes? ¿Ejecución condicional, tal vez?

2 answers

Es una desagradable fuga de abstracción heredada.

El diseño ARM original tenía una canalización de 3 etapas (fetch-decode-execute). Para simplificar el diseño, optaron por tener el PC leído como el valor actual en las líneas de direcciones de recuperación de instrucciones, en lugar de la instrucción que se ejecuta actualmente de hace 2 ciclos. Dado que la mayoría de las direcciones relativas a PC se calculan en el momento del enlace, es más fácil que el ensamblador/enlazador compense ese desplazamiento de 2 instrucciones que diseñar todo el lógica para 'corregir' el registro del PC.

Por supuesto, todo eso está firmemente en la pila de "cosas que tenían sentido hace 30 años". Ahora imagine lo que se necesita para mantener un valor significativo en ese registro en la etapa actual de 15+, múltiples problemas, canalizaciones fuera de orden, y podría apreciar por qué es difícil encontrar un diseñador de CPU en estos días que piense que exponer el PC como un registro es una buena idea.

Aún así, por el lado positivo, al menos no es tan horrible como delay slots. En su lugar, contrariamente a lo que supone, tener cada instrucción ejecutada condicionalmente era realmente solo otra optimización alrededor de ese desplazamiento de prefetch. En lugar de tener que tomar siempre retrasos de flujo de tuberías cuando se ramifican alrededor del código condicional (o aún ejecutando lo que queda en la tubería como una persona loca), puede evitar ramas muy cortas por completo; la tubería permanece ocupada, y las instrucciones decodificadas pueden ejecutarse como NOPs cuando las banderas no coinciden*. Una vez más, estos días tenemos predictores de rama eficaces y termina siendo más un obstáculo que una ayuda, pero para 1985 fue genial.

* "...el conjunto de instrucciones con la mayoría de NOPs en el planeta."

 43
Author: Notlikethat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-24 00:09:23

Eso es cierto...

Un ejemplo está a continuación: C programa:

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;
}

Compilar para ensamblar:

    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

Vea el valor de PC de LDR anterior here aquí se usa para cargar la dirección de la variable f,g,y a r3.

    83a0: e59f301c ldr r3, [pc, #28];83c4 main+0x2c
    PC=0x83c4-28=0x83a8-0x1C = 0x83a8

El valor de PC es solo la instrucción de ejecución siguiente de la instrucción siguiente. como ARM usa instrucciones de 32bits, pero está usando la dirección de bytes, por lo que + 8 significa 8bytes, la longitud de dos instrucciones.

Tan unido ARM archi 5 stage pipe linefetch, decodificar, ejecutar, memoria, writeback

Tubería de 5 etapas del BRAZO

El registro de PC se agrega por 4 cada reloj, por lo que cuando la instrucción burbujeó para ejecutar the la instrucción actual, el registro de PC ya pasó 2 reloj! ahora es + 8. eso en realidad significa: PC señala la instrucción "fetch", la instrucción actual significa la instrucción" execute", por lo que PC significa la siguiente siguiente a ser ejecutada.

POR cierto: la foto es del libro de Harris de Diseño Digital y Arquitectura de Computadoras ARM Edition

 0
Author: Harry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-10 11:21:34