Instrucciones de salto condicional en el Mips

De Wikitronica
Revisión del 20:41 6 may 2013 de Irene López (Discusión | contribuciones) (Introducción a los Saltos Condicionales en MIPS)

Saltar a: navegación, buscar

Introducción a los Saltos Condicionales en MIPS

Los saltos condicionales son aquellas instrucciones en las cuales primero se realiza una comparación entre el contenido de dos registros o variables y dependiendo del resultado obtenido se realiza un salto a alguna etiqueta o posición de memoria.

La habilidad de tomar desiciones es lo que diferencia a una computadora de una simple calculadora. Basandose en los datos de entrada y los valores creados al momento de programar, diferentes instrucciones pueden ser ejecutadas. La toma de desiciones es comunmente representada en lenguajes de programación mediante la instruccion if, algunas veces combinada con la instruccion "go to" y etiquetas.

El lenguaje ensamblador MIPS incluye 12 instrucciones básicas condicionales o de toma de decisión, sin embargo también hay instrucciones condicionales extendidas (pseudoinstrucciones), muchas de estas instrucciones tienen distintos modos de direccionamiento, que permiten utilizar operandos de 8, 16 y 32 bits.

Instrucciones Básicas

Branch if Equal (BEQ)

  • Formato de la instrucción:
beq $t1, $t2, etiqueta

Donde $t1 y $t2 son los registros a comparar y "etiqueta" es a donde se desea saltar (Recordar que los registros de $t0-$t7 se utilizan para almacenar valores temporales)

Esta instrucción compara los valores de dos registros ($t1 y $t2), y si resultan ser iguales el flujo del programa salta a la instrucción que corresponda a la etiqueta colocada. De no ser iguales se ejecuta la siguiente instrucción en el código.

Branch if not Equal (BNE)

  • Formato de la instrucción:
bne $t1, $t2, etiqueta

Donde $t1 y $t2 son los registros a comparar y "etiqueta" es a donde se desea saltar

En este caso se realiza la comparación y si los valores en ambos registros no resultan iguales el programa salta a la instrucción que corresponde a la etiqueta. Si resultan iguales se ejecutara la siguiente instrucción.

  • Branch if greater than or equal to zero

Branch if greater than or equal to zero

  • Formato de la instruccion:
bgez $t1, etiqueta

Si el contenido de $t1 es mayor o igual a cero, el flujo del programa salta a la instrucción correspondiente a la etiqueta colocada

Branch if grater than or equal to zero and link

  • Formato de la instruccion:
bgezal $t1, etiqueta

Si el contenido de $t1 es mayor o igual a cero, se carga el registro $ra (return adress) con el contador de programa (PC) y se salta a la instrucción correspondiente a la etiqueta utilizada.

Branch if greater than zero

  • Formato de la instruccion:
bgtz $t1, etiqueta

Si el contenido de $t1 es mayor que cero, el flujo de programa salta a la etiqueta colocada. Si es menor que cero se realiza la siguiente instruccion en el codigo

Branch if less than or equal to zero

  • Formato de la instruccion:
blez $t1, etiqueta

Si el contenido de $t1 es menor o igual a cero, el flujo del programa salta a la etiqueta colocada. Si es mayor que cero se realiza la siguiente instrucción en el código

Branch if less than zero

  • Fotmato de la instrucción:


bltz $t1, etiqueta

Si el contenido de $t1 es menor que cero el flujo del programa salta a la etiqueta colocada. Si es mayor que cero se realiza la siguiente instrucción en el código

Branch if less than zero and link

  • Formato de la instrucción:
bltzal $t1, etiqueta

Si el contenido de $t1 es menor que cero, se carga el registro $ra (return adress) con el contador de programa (PC) y se salta a la dirección de la etiqueta utilizada.


Branch if FP condition flag 0 (false)

  • Formato de la instrucción:
bc1f  etiqueta


La comparacion en punto flotante coloca un bit en uno (verdadero) o cero (falso), si el bit esta en cero el flujo del programa salta a la etiqueta colocada, en caso contrario se realiza la siguiente instrucción en el código. Es decir:

if(!Condición en Punto flotante)

PC=PC+4+Direccion de la "etiqueta"


Branch if FP condition flag 0 (false) con una bandera especifica

  • Formato de la instrucción:
bc1f imm,etiqueta


En Mips se tienen 8 banderas para la comparación en punto flotante; cuando no se especifica la bandera en la instrucción, se trabaja de forma predeterminada con la cero.


En esta instrucción, la comparación en punto flotante coloca la bandera especificada por el operando inmediato "imm", en uno (verdadero) o cero (falso), si el bit esta en cero el flujo del programa salta a la etiqueta colocada, en caso contrario se realiza la siguiente instrucción en el código.

Branch if FP condition flag 1 (true)

  • Formato de la instrucción:
bc1t etiqueta


La comparación en punto flotante coloca un bit en uno (verdadero) o cero (falso), si el bit esta en uno el flujo del programa salta a la etiqueta colocada, en caso contrario se realiza la siguiente instrucción en el código. Es decir:


if(Condición en Punto flotante)

PC=PC+4+ Dirección de la "etiqueta"


Branch if FP condition flag 1 (true) con una bandera especifica

  • Formato de la instrucción:
bc1t  imm,etiqueta


En Mips se tienen 8 banderas para la comparación en punto flotante; cuando no se especifica la bandera en la instrucción, se trabaja de forma predeterminada con la cero.


En esta instrucción, la comparación en punto flotante coloca la bandera especificada por el operando inmediato "imm", en uno (verdadero) o cero (falso), si el bit esta en uno el flujo del programa salta a la etiqueta colocada, en caso contrario se realiza la siguiente instrucción en el código.

Instrucciones Extendidas

Branch if Equal

  • Formato de la instrucción:
beq $r1, imm, etiqueta

Donde "$r1" es un registro, "imm" es un operando inmediato de 16 o 32 bits (por ejemplo "100" o "10000"), y "etiqueta" es a donde se desea saltar

Esta instrucción compara el valor de $r1 con el de imm y si resultan ser iguales el flujo del programa salta a la instrucción que corresponda a la etiqueta colocada. De no ser iguales se ejecuta la siguiente instrucción en el código. Es decir:

if(R[rs]==imm)

PC=Direccion de la "etiqueta"


Branch if EQual Zero

  • Formato de la instrucción:
beqz $r1,etiqueta

Donde "$r1" es un registro y "etiqueta" es a donde se desea saltar.

Esta instrucción comprueba si en el registro $r1 hay un cero, de ser asi el flujo del programa salta a la instrucción que corresponda a la etiqueta colocada. En caso contrario se ejecuta la siguiente instrucción en el código. Es decir:

if(R[r1]==0)

PC=Direccion de la "etiqueta"


Branch if Greater or Equal

  • Formato de la instrucción:
bge $r1,t2,etiqueta

Donde "etiqueta" es a donde se desea saltar, "$r1" es un registro y "t2" puede ser otro registro ($r2) o un operando inmediato de 16 o 32 bits (por ejemplo "100" o "10000").

Esta instrucción compara el valor de $r1 con el de t2, y si $r1 es mayor o igual que t2 el flujo del programa salta a la instrucción que corresponda a la etiqueta colocada. En caso contrario se ejecuta la siguiente instrucción en el código. Es decir:

if(R[r1]>=t2)

PC=Direccion de la "etiqueta"


Branch if Greater or Equal Unsigned

  • Formato de la instrucción:
bgeu $r1,t2,etiqueta

Donde "etiqueta" es a donde se desea saltar, "$r1" es un registro y "t2" puede ser otro registro ($r2) o un operando inmediato de 16 o 32 bits (por ejemplo "100" o "10000").

Esta instrucción actúa como BGE, pero sin tomar en cuenta el signo de $r1 y t2. Es decir:

if( |R[r1]| >= |t2| )

PC=Direccion de la "etiqueta"


Branch if Greater Than

  • Formato de la instrucción:
bgt $r1,t2,etiqueta

Donde "etiqueta" es a donde se desea saltar, "$r1" es un registro y "t2" puede ser otro registro ($r2) o un operando inmediato de 16 o 32 bits (por ejemplo "100" o "10000").

Esta instrucción compara el valor de $r1 con el de t2, y si $r1 es mayor que t2 el flujo del programa salta a la instrucción que corresponda a la etiqueta colocada. En caso contrario se ejecuta la siguiente instrucción en el código. Es decir:

if(R[r1]>t2)

PC=Direccion de la "etiqueta"


Branch if Greater Than Unsigned

  • Formato de la instrucción:
bgtu $r1,t2,etiqueta

Donde "etiqueta" es a donde se desea saltar, "$r1" es un registro y "t2" puede ser otro registro ($r2) o un operando inmediato de 16 o 32 bits (por ejemplo "100" o "10000"). Esta instrucción actúa como BGT, pero sin tomar en cuenta el signo de $r1 y t2. Es decir:

if( |R[r1]| > |t2| )

PC=Direccion de la "etiqueta"


Branch if Less or Equal

  • Formato de la instrucción:
ble $r1,t2,etiqueta

Donde "etiqueta" es a donde se desea saltar, "$r1" es un registro y "t2" puede ser otro registro ($r2) o un operando inmediato de 16 o 32 bits (por ejemplo "100" o "10000").

Esta instrucción compara el valor de $r1 con el de t2, y si $r1 es menor o igual que t2 el flujo del programa salta a la instrucción que corresponda a la etiqueta colocada. En caso contrario se ejecuta la siguiente instrucción en el código. Es decir:

if(R[r1]<=t2)

PC=Direccion de la "etiqueta"


Branch if Less or Equal Unsigned

  • Formato de la instrucción:
bleu $r1,t2,etiqueta

Donde "etiqueta" es a donde se desea saltar, "$r1" es un registro y "t2" puede ser otro registro ($r2) o un operando inmediato de 16 o 32 bits (por ejemplo "100" o "10000").

Esta instrucción actúa como BLE, pero sin tomar en cuenta el signo de $r1 y t2. Es decir:

if( |R[r1]| <= |t2| )

PC=Direccion de la "etiqueta"


Branch if Less Than

  • Formato de la instrucción:
blt $r1,t2,etiqueta

Donde "etiqueta" es a donde se desea saltar, "$r1" es un registro y "t2" puede ser otro registro ($r2) o un operando inmediato de 16 o 32 bits (por ejemplo "100" o "10000").

Esta instrucción compara el valor de $r1 con el de t2, y si $r1 es menor que t2 el flujo del programa salta a la instrucción que corresponda a la etiqueta colocada. En caso contrario se ejecuta la siguiente instrucción en el código. Es decir:

if(R[r1]<t2)

PC=Direccion de la "etiqueta"


Branch if Less Than Unsigned

  • Formato de la instrucción:
bltu $r1,t2,etiqueta

Donde "etiqueta" es a donde se desea saltar, "$r1" es un registro y "t2" puede ser otro registro ($r2) o un operando inmediato de 16 o 32 bits (por ejemplo "100" o "10000").

Esta instrucción actúa como BLT, pero sin tomar en cuenta el signo de $r1 y t2. Es decir:

if( |R[r1]| < |t2| )

PC=Direccion de la "etiqueta"


Branch if Not Equal

  • Formato de la instruccion:
bne $r1,imm, etiqueta

Donde "$r1" es un registro, "imm" es un operando inmediato de 16 o 32 bits (por ejemplo "100" o "10000"), y "etiqueta" es a donde se desea saltar

Esta instrucción compara el valor de $r1 con el de imm y si no son iguales el flujo del programa salta a la instrucción que corresponda a la etiqueta colocada. De ser iguales se ejecuta la siguiente instrucción en el código. Es decir:

if(R[rs]!=imm)

PC=Direccion de la "etiqueta"


Branch if Not Equal Zero

  • Formato de la instrucción:
bnez $r1,etiqueta

Donde "$r1" es un registro y "etiqueta" es a donde se desea saltar.

Esta instrucción comprueba si en el registro $r1 hay un cero, de no ser asi el flujo del programa salta a la instrucción que corresponda a la etiqueta colocada. En caso contrario se ejecuta la siguiente instrucción en el código. Es decir:

if(R[r1]!=0)

PC=Direccion de la "etiqueta"

Ejemplos

Como convertir un if-else en lenguaje C a branch condicionales en MIPS

Codigo en C:

if(i==j)
f=g+h;
else f=g-h;

Codigo en MIPS:

Supongamos que el valor de i se encuentra en el registro $s3, j se encuentra en $s4, g se encuentra en $s1 y h en $s2, entonces:

bne $s3, $s4, Else       # ir a Else si i!=j
add $s0, $s1, $s2        # suma g+h y lo guarda en $s0 (si i==j)
j Exit                   # salir
Else: sub $s0, $s1, $s2  # f=g-h (si i!=j)
Exit:                    # termina el programa


Como utilizar las instrucciones branch con condicion FP (floating point)

.data
A:		.float   3.56
B:		.float   7.33
texto_true:	.asciiz "TRUE :)"
texto_false: 	.asciiz "FALSE :("

.text
#cargo los registros $f0,$f1 con A,B respectivamente

	l.s $f0,A
	l.s $f1,B

#comparo: $f0>$f1? y uso ARBITRARIAMENTE de las "banderas de comparaciones de numeros FLOTANTES"
#En este caso se usa la numero 3 de un total de 8 disponibles
	c.le.s 3,$f0, $f1

# Verifico la bandera utilizada para hacer un salto: 

	bc1t 3,condicion_true

condicion_false: 
	li  $v0, 4
	la $a0, texto_false
	syscall               # se imprime 'FALSE'
	j fin
      
condicion_true:
	li  $v0, 4
	la $a0, texto_true
	syscall               # se imprime 'TRUE'

fin:	
	#syscall para salir
      li   $v0, 10
      syscall

Contributors

CeMoron, Irene López, JCaceres