7 votos

Instrucción NOP después del rama de ARMv7 Cortex M3

Estoy interesado, ¿por qué para el Cortex M3 microcontrolador (stm32f103) compilador genera una instrucción NOP después de la sucursal. Y por qué a veces no.

Por ejemplo:

0x08000496 2400      MOVS     r4,#0x00
0x08000498 4625      MOV      r5,r4
0x0800049A E006      B        0x080004AA
    64: res=res+a[i];
    65: }
0x0800049C F85A0034  LDR      r0,[r10,r4,LSL #3] // No NOP after B
0x080004A0 EB100808  ADDS     r8,r0,r8
0x080004A4 1C64      ADDS     r4,r4,#1
0x080004A6 F1450500  ADC      r5,r5,#0x00
0x080004AA 1BA0      SUBS     r0,r4,r6
0x080004AC EB750007  SBCS     r0,r5,r7
0x080004B0 DBF4      BLT      0x0800049C
    66: int64_t avg=res/x;
0x080004B2 BF00      NOP      // <------------------- NOP after BLT
    69: int v=countbits1(5);
0x080004B4 2005      MOVS     r0,#0x05
0x080004B6 F7FFFFA2  BL.W     countbits1 (0x080003FE)
0x080004BA 9001      STR      r0,[sp,#0x04]     // No NOP after BL.W
    72: unsigned int b=countLeadingZeros(5);
    73:  
0x080004BC 2005      MOVS     r0,#0x05

Mi primera suposición era que el tiempo de instrucción de las necesidades de la alineación de palabra, sino BL.W después NOP en realidad no lo tiene. Si esto NOP es relativa a la tubería de alguna manera que ¿por qué hay ramas sin nop después de ellos?

Estoy confundido.

ACTUALIZACIÓN:

Resulta que la rama no puede ser relevante en absoluto. Traté de mover declaración de que no se utilicen variable local int64_t avg - y NOP se trasladó junto con él. Así que yo beleive pjc50 comentario es correcto y esta NOP es solo para dejar depurador de poner un breakpoint en esta línea.

4voto

Omer Eldan Puntos 106

Muchos (la mayoría? todos?) los compiladores de terminar poniendo NOP instrucciones después de algunos (pero no otros) saltar de la rama tipo de instrucciones.

Cuando el compilador ve un "salto" tipo de la instrucción, que tiene dos instrucciones diferentes que pueden hacer el trabajo. Uno es relativo, uno es absoluta.

Uno es un pariente de salto, y uno es un absoluto de salto. La relación de salto es más rápido, y especifica un salto relativo a la instrucción de la dirección para saltar a un único byte, por lo que puede saltar hacia adelante 128 bytes, o hacia atrás 127 bytes.

El otro es un absoluto de salto - esto es más lento, y especifica la dirección a la que hay que saltar. Esto puede saltar a cualquier lugar.

El problema es que, cuando al saltar hacia adelante, la dirección de destino no puede ser conocido aún tendría que compilar el código, hasta el destino de salto, para luego resolver si es menos de 128 bytes. Por supuesto, para averiguar a cuántos bytes para saltar hacia adelante, usted necesita saber cuántos bytes de ESTA instrucción toma, así como todas las instrucciones entre aquí y allí.

Esta es la forma fuera de la paygrade de un compilador; deja espacio para una absoluta salto, a continuación, en el segundo paso, cuando se sabe donde todas las direcciones, se llena los vacíos - colocando en una más eficiente relativa salto (+ NOP, porque tiene que tener el mismo número de bytes!), o poniendo en absoluto de salto.

1voto

jns Puntos 449

Mueva la línea de int64_t de C hacia arriba o hacia abajo un poco. Las dos primeras son claramente parte de un bucle; pero línea 66 no ha generado ningún código en absoluto. Mi conjetura es que el NOP es en beneficio del depurador para que cada línea de C genera al menos una instrucción.

(No todos los depuradores para ello en todas las plataformas; Visual Studio simplemente moverá el breakpoint a la línea más cercana que tiene código asociado con él.)

0voto

carlab Puntos 1

Cortex-M3 de los microcontroladores están construidas con una arquitectura de 32 bits, pero no limitar las entradas para este tamaño del bus (ver http://www.silabs.com/Support%20Documents/TechnicalDocs/EFM32-Cortex-M3-RM.pdf). La arquitectura tiene un pequeño prefetch buffer para manejar el caso de los no alineados palabra instrucciones para que, cuando la rama se toma usted no tiene un problema. Cuando la rama no es tomado es necesario vaciar la tubería para eliminar el error de la elección y a buscar de nuevo. No se puede recuperar directamente desde 0x080004B2 como este no es de 4 bytes alineado y si se obtienen de 0x080004B0 sería volver a leer la rama. El NOP es entonces esencial para el relleno extra que necesita para obtener de la palabra alineada 0x080004B4 y continuar desde allí.

http://community.arm.com/groups/embedded/blog/2014/11/07/intern-inquiry-1031--assembly-on-cortex-m3-question

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X