Instrucciones de salto condicional en el Mips
Contenido
- 1 Introducción a los Saltos Condicionales en MIPS
- 2 Instrucciones Básicas
- 2.1 Branch if Equal
- 2.2 Branch if not Equal
- 2.3 Branch if greater than or equal to zero
- 2.4 Branch if greater than or equal to zero and link
- 2.5 Branch if greater than zero
- 2.6 Branch if less than or equal to zero
- 2.7 Branch if less than zero
- 2.8 Branch if less than zero and link
- 2.9 Branch if FP condition flag 0 (false)
- 2.10 Branch if FP condition flag 0 (false) con una bandera especifica
- 2.11 Branch if FP condition flag 1 (true)
- 2.12 Branch if FP condition flag 1 (true) con una bandera especifica
- 3 Instrucciones Extendidas
- 3.1 Branch if Equal
- 3.2 Branch if EQual Zero
- 3.3 Branch if Greater or Equal
- 3.4 Branch if Greater or Equal Unsigned
- 3.5 Branch if Greater Than
- 3.6 Branch if Greater Than Unsigned
- 3.7 Branch if Less or Equal
- 3.8 Branch if Less or Equal Unsigned
- 3.9 Branch if Less Than
- 3.10 Branch if Less Than Unsigned
- 3.11 Branch if Not Equal
- 3.12 Branch if Not Equal Zero
- 4 Ejemplos
- 5 Referencias
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 decisiones 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. También existen saltos incondicionales.
Instrucciones Básicas
Branch if Equal
- 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
- 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
- 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 greater 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
- Formato 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
Referencias
- Ayuda de MARS (Mips Assembler and Runtime Simulator)