Pregunta Instrucciones de salto en la Asamblea de MIPS


Aquí hay un código de ensamblaje MIPS que escribí para probar la instrucción de salto:

addi $a0, $0, 1
j next
next:
j skip1
add $a0, $a0, $a0
skip1:
j skip2:
add $a0, $a0, $a0
add $a0, $a0, $a0
skip2:
j skip3
loop:
add $a0, $a0, $a0
add $a0, $a0, $a0
add $a0, $a0, $a0
skip3:
j loop

Cuando ejecuto el ensamblador, aquí está el resultado:

[0x000000]  0x20040001  # addi $a0, $zero, 1 ($a0 = 1)
[0x000004]  0x08000002  # j 0x0002 (jump to addr 0x0008)
[0x000008]  0x08000004  # j 0x0004 (jump to addr 0x0010)
[0x00000C]  0x00842020  # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x000010]  0x08000007  # j 0x0007 (jump to addr 0x001C)
[0x000014]  0x00842020  # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x000018]  0x00842020  # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x00001C]  0x0800000B  # j 0x000B (jump to addr 0x002C)
[0x000020]  0x00842020  # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x000024]  0x00842020  # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x000028]  0x00842020  # add $a0, $a0, $a0 ($a0 = $a0 + $a0)
[0x00002C]  0x08000008  # j 0x0008 (jump to addr 0x0020)

Mirando el código de máquina para las instrucciones de salto, esto es lo que veo:

1st jump (just jumps to next instruction) 0x08000002
2nd jump (skips 1 instruction) 0x08000004
3rd jump (skips 2 instructions) 0x08000007
4th jump (skips 3 instructions) 0x0800000B
5th jump (skips 3 instructions backwards) 0x08000008

Al observar estas instrucciones, parece que el código de máquina comienza con un 08 para la instrucción de salto, y el número al final le dice a la instrucción de salto dónde ir. Sin embargo, no puedo entender cómo se calcula este número. Además, no hay nada que me indique que el quinto salto es un salto hacia atrás.

¿Cómo se calcula el valor de salto?


7
2017-10-24 14:43


origen


Respuestas:


Solo mire en un manual de referencia para más detalles sobre la codificación del código de operación.

Versión corta: en una instrucción de 32 bits, no puede incluir un destino de salto de 32 bits. El código de operación usa 6 bits, lo que deja 26 bits para la instrucción. La dirección de destino se construye tomando los primeros 4 bits de la dirección de la instrucción que sigue al j instrucción, entonces se añaden 2 bits cero a los 26 bits del operando de instrucción de salto. (Como las instrucciones son 32 bits, la alineación es útil y permite omitir los dos últimos 0).

Para el salto hacia atrás: las direcciones son absolutas, NO relativas, por lo que solo depende de la dirección de la instrucción de salto, ya sea un avance o retroceso.

EDITAR: Descripción más detallada: Tenemos en la dirección X instrucción de salto j. Dejar t representar el operando de salto de j. t tiene 26 bits de ancho. El patrón de bits de la dirección de la siguiente instrucción se calcula de la siguiente manera:

upper_6_bits_of(x+4),t,0,0

Entonces el salto es SIEMPRE absoluto. No hay saltos relativos. cuando el resultado es menor que x, entonces es un salto hacia atrás, cuando es mayor, es un salto hacia adelante (y si quieres algo estúpido, lo haces igual ;-).

Así que veamos el quinto salto de su ejemplo:

Los primeros 6 bits del objetivo de salto son: 000000, porque los 6 bits superiores de la dirección de la instrucción detrás del salto son 000000.

Los siguientes 26 bits son los 26 bits más bajos de la instrucción de salto, es decir, 00000000000000000000001000

Los últimos 2 bits son: 00, porque siempre se anexó.

Juntos tenemos: 0000000000000000000000000000100000, que es hex 20. Y en esa dirección está exactamente la etiqueta / instrucción donde el flujo debe continuar.


12
2017-10-24 14:51



En MIPS, J es una instrucción de tipo J:

J-type instructions (Jumps)
3    22
1    65                        0
+----+-------------------------+
| op |         target          |
+----+-------------------------+

Entonces tenemos un target eso es 26 bits de largo. Se combina con la PC de la siguiente instrucción de la siguiente manera:

I
I+1 PC <- (PC & 0xf0000000) | (target << 2)

Se desplaza a la izquierda 2 bits, ya que las instrucciones MIPS (ignorando la extensión MIPS16) tienen 32 bits de longitud, lo que significa que todas comienzan en una dirección cuyos 2 bits inferiores son cero.


6
2017-10-24 18:42