2011-08-05 15 views

Respuesta

53

1. Dirección de la sucursal Cálculo

En MIPS, la instrucción de bifurcación tiene solo 16 bits de desplazamiento para determinar la siguiente instrucción. Necesitamos un registro agregado a este valor de 16 bits para determinar la siguiente instrucción y este registro está realmente implicado por la arquitectura. Es un registro de PC ya que la PC se actualiza (PC + 4) durante el ciclo de búsqueda para que contenga la dirección de la siguiente instrucción. También limitamos la distancia de bifurcación a la instrucción -2^15 to +2^15 - 1 de la instrucción de bifurcación (instrucción después de). Sin embargo, esto no es un problema real ya que la mayoría de las sucursales son locales de todos modos.

Así que paso a paso:

  • sesión extender el valor de desplazamiento de 16 bits para conservar su valor.
  • Multiplique el valor resultante con 4. La razón detrás de esto es que si vamos a ramificar alguna dirección, y la PC ya está alineada, entonces el valor inmediato debe estar alineado con la palabra también. Sin embargo, no tiene sentido hacer la alineación de palabras inmediata porque estaríamos desperdiciando dos bits al forzarlos a ser 00.
  • Ahora tenemos la dirección de 32 bits. Agregue este valor a PC + 4 y esa es su dirección de sucursal.

Branch address calculation


2. Saltar Dirección Cálculo

Para la instrucción de salto Mips tiene sólo 26 bits para determinar la ubicación de salto. Además, los saltos son relativos a la PC en MIPS. Al igual que la rama, el valor de salto inmediato debe estar alineado con la palabra, por lo tanto, debemos multiplicar la dirección de 26 bits por cuatro.

paso a paso Una vez más:

  • valor del bit Multiplicar 26 con 4.
  • Dado que estamos saltando con respecto al valor de PC, concatenar primeros cuatro bits del valor de la PC a la izquierda de nuestra dirección de salto.
  • La dirección resultante es el valor de salto.

En otras palabras, reemplazar las inferiores 28 bits de la PC con los inferiores 26 bits de la instrucción extraída desplazado a la izquierda por 2 bits.

enter image description here

Fuente: Universidad de Bilkent CS 224 Curso Diapositivas

+1

Explicación fantástica, +1 – Ephemera

+0

¿por qué "concatenar los primeros cuatro bits del valor de PC a la izquierda de nuestra dirección de salto"? – NoName

+0

Por favor marque @ user786653 answer. Él explica el concepto de salto relativo al valor de PC con más detalle. –

-1

Creo que sería bastante difícil de calcular porque la dirección de destino de la sucursal se determina en tiempo de ejecución y esa predicción se realiza en el hardware. Si explicara el problema un poco más en profundidad y describiera lo que está tratando de hacer, sería un poco más fácil ayudarlo. (:

+0

MIPS instrucciones de bifurcación todos tienen un objetivo inmediato (desplazamiento relativo al programa actual). Las instrucciones de control de flujo que toman una fuente de registro para la dirección de destino son 'jr'. A menos que estés siendo tonto y consideres el fracaso como una dirección objetivo para el caso no tomado. –

15

Por lo general, usted no tiene que preocuparse acerca de cómo calcular como su ensamblador (o enlazador) tendrá de obtener los cálculos adecuados Digamos que usted tiene una pequeña función:.


func: 
    slti $t0, $a0, 2 
    beq $t0, $zero, cont 
    ori $v0, $zero, 1 
    jr $ra 
cont: 
    ... 
    jal func 
    ... 

Al traducir la encima del código en una secuencia binaria de instrucciones que el ensamblador (o vinculador si primero ensambló en un archivo objeto) se determinará en qué lugar de la memoria residirá la función (ignoremos por ahora el código de posición independiente). En qué lugar de la memoria residirá normalmente se especifica en el ABI o se le da a usted si está usando un simulador (como SPIM que carga el código en 0x400000 - tenga en cuenta que el enlace también contiene una buena explicación de el proceso).

Suponiendo que estamos hablando del caso SPIM y nuestra función es la primera en la memoria, la instrucción slti residirá en 0x400000, el beq en 0x400004 y así sucesivamente. ¡Ahora casi llegamos! Para la instrucción beq la dirección de destino rama es el de cont (0x400010) mirando una MIPS instruction reference vemos que se codifica como 16 bits con signo pariente inmediato a la siguiente instrucción (dividido por 4, como todas las instrucciones deben residir en una Dirección de 4 bytes alineados de todos modos).

Es decir:

Current address of instruction + 4 = 0x400004 + 4 = 0x400008 
Branch target = 0x400010 
Difference = 0x400010 - 0x400008 = 0x8 
To encode = Difference/4 = 0x8/4 = 0x2 = 0b10 

Codificación de beq $t0, $zero, cont

0001 00ss ssst tttt iiii iiii iiii iiii 
--------------------------------------- 
0001 0001 0000 0000 0000 0000 0000 0010 

Como se puede ver se puede acceder a -0x1fffc .. 0x20000 dentro bytes. Si por alguna razón necesitas saltar más, puedes usar un trampolín (un salto incondicional al objetivo real colocado dentro del límite dado).

destino del salto se ocupa de son, a diferencia de las direcciones de destino del salto, codificados utilizando el dirección absoluta (de nuevo dividido por 4). Como la codificación de la instrucción usa 6 bits para el código de operación, esto solo deja 26 bits para la dirección (efectivamente 28 dado que los 2 últimos bits serán 0), por lo tanto, los 4 bits más significativos del registro de PC se usan cuando se forma la dirección (no importará a menos que intente saltar a través de los límites de 256 MB).

Volviendo al ejemplo anterior la codificación para jal func es:

Destination address = absolute address of func = 0x400000 
Divided by 4 = 0x400000/4 = 0x100000 
Lower 26 bits = 0x100000 & 0x03ffffff = 0x100000 = 0b100000000000000000000 

0000 11ii iiii iiii iiii iiii iiii iiii 
--------------------------------------- 
0000 1100 0001 0000 0000 0000 0000 0000 

puede verificar con rapidez esto, y jugar con diferentes instrucciones, el uso de este online MIPS assembler me encontré con (tenga en cuenta que no es compatible con todos los códigos de operación , por ejemplo slti, por lo que acabo de cambiar a slt aquí):

00400000: <func> ; <input:0> func: 
00400000: 0000002a ; <input:1> slt $t0, $a0, 2 
00400004: 11000002 ; <input:2> beq $t0, $zero, cont 
00400008: 34020001 ; <input:3> ori $v0, $zero, 1 
0040000c: 03e00008 ; <input:4> jr $ra 
00400010: <cont> ; <input:5> cont: 
00400010: 0c100000 ; <input:7> jal func 
+0

Oh hey, encontraste mi ensamblador MIPS en línea :) –

+0

FYI, si alguien está interesado en agregar instrucciones (como 'slti'), no dude en enviar solicitudes de extracción a https://github.com/alanhogan/online-mips -ensamblador. –

0

Para las pequeñas funciones como ésta que acaba podía contar con la mano el número de saltos que es el objetivo, a partir de la instrucción bajo la instrucción de salto . Si se ramifica hacia atrás, ese número de salto será negativo. si ese número no requiere los 16 bits, entonces para cada número a la izquierda del número de saltos más significativo, hazlos de 1, si el número de saltos es positivo hazlos todos 0 ya que la mayoría de las ramas están cerca de ellos objetivos, esto le ahorra una gran cantidad de aritmética extra para la mayoría de los casos.

  • Chris
Cuestiones relacionadas