Montaje - Condiciones
La ejecución condicional en lenguaje ensamblador se logra mediante varias instrucciones de bucle y ramificación. Estas instrucciones pueden cambiar el flujo de control en un programa. La ejecución condicional se observa en dos escenarios:
No Señor. | Instrucciones condicionales |
---|---|
1 | Unconditional jump Esto se realiza mediante la instrucción JMP. La ejecución condicional a menudo implica una transferencia de control a la dirección de una instrucción que no sigue la instrucción que se está ejecutando actualmente. La transferencia de control puede ser hacia adelante, para ejecutar un nuevo conjunto de instrucciones o hacia atrás, para volver a ejecutar los mismos pasos. |
2 | Conditional jump Esto se realiza mediante un conjunto de instrucciones de salto j <condición> dependiendo de la condición. Las instrucciones condicionales transfieren el control rompiendo el flujo secuencial y lo hacen cambiando el valor de compensación en IP. |
Analicemos la instrucción CMP antes de discutir las instrucciones condicionales.
Instrucción CMP
La instrucción CMP compara dos operandos. Generalmente se usa en ejecución condicional. Esta instrucción básicamente resta un operando del otro para comparar si los operandos son iguales o no. No perturba los operandos de origen o destino. Se utiliza junto con la instrucción de salto condicional para la toma de decisiones.
Sintaxis
CMP destination, source
CMP compara dos campos de datos numéricos. El operando de destino puede estar en el registro o en la memoria. El operando de origen podría ser un registro, memoria o datos constantes (inmediatos).
Ejemplo
CMP DX, 00 ; Compare the DX value with zero
JE L7 ; If yes, then jump to label L7
.
.
L7: ...
CMP se utiliza a menudo para comparar si un valor de contador ha alcanzado el número de veces que se debe ejecutar un bucle. Considere la siguiente condición típica:
INC EDX
CMP EDX, 10 ; Compares whether the counter has reached 10
JLE LP1 ; If it is less than or equal to 10, then jump to LP1
Salto incondicional
Como se mencionó anteriormente, esto se realiza mediante la instrucción JMP. La ejecución condicional a menudo implica una transferencia de control a la dirección de una instrucción que no sigue la instrucción que se está ejecutando actualmente. La transferencia de control puede ser hacia adelante, para ejecutar un nuevo conjunto de instrucciones o hacia atrás, para volver a ejecutar los mismos pasos.
Sintaxis
La instrucción JMP proporciona un nombre de etiqueta donde el flujo de control se transfiere inmediatamente. La sintaxis de la instrucción JMP es:
JMP label
Ejemplo
El siguiente fragmento de código ilustra la instrucción JMP:
MOV AX, 00 ; Initializing AX to 0
MOV BX, 00 ; Initializing BX to 0
MOV CX, 01 ; Initializing CX to 1
L20:
ADD AX, 01 ; Increment AX
ADD BX, AX ; Add AX to BX
SHL CX, 1 ; shift left CX, this in turn doubles the CX value
JMP L20 ; repeats the statements
Salto condicional
Si se satisface alguna condición especificada en el salto condicional, el flujo de control se transfiere a una instrucción de destino. Existen numerosas instrucciones de salto condicionales según la condición y los datos.
A continuación se muestran las instrucciones de salto condicional que se utilizan en datos con signo utilizados para operaciones aritméticas:
Instrucción | Descripción | Banderas probadas |
---|---|---|
JE / JZ | Saltar igual o saltar cero | ZF |
JNE / JNZ | Saltar no igual o Saltar no cero | ZF |
JG / JNLE | Saltar mayor o no menos / igual | OF, SF, ZF |
JGE / JNL | Saltar mayor / igual o no saltar menos | OF, SF |
JL / JNGE | Saltar menos o saltar no mayor / igual | OF, SF |
JLE / JNG | Saltar menos / igual o no saltar mayor | OF, SF, ZF |
A continuación se muestran las instrucciones de salto condicional que se utilizan en datos sin firmar utilizados para operaciones lógicas:
Instrucción | Descripción | Banderas probadas |
---|---|---|
JE / JZ | Saltar igual o saltar cero | ZF |
JNE / JNZ | Saltar no igual o Saltar no cero | ZF |
JA / JNBE | Saltar por encima o no saltar por debajo / igual | CF, ZF |
JAE / JNB | Saltar por encima / igual o no saltar por debajo | CF |
JB / JNAE | Saltar abajo o no saltar arriba / igual | CF |
JBE / JNA | Saltar abajo / igual o no saltar arriba | AF, CF |
Las siguientes instrucciones de salto condicional tienen usos especiales y verifican el valor de las banderas:
Instrucción | Descripción | Banderas probadas |
---|---|---|
JXCZ | Saltar si CX es cero | ninguna |
JC | Saltar si llevar | CF |
JNC | Salta si no llevas | CF |
JO | Saltar si se desborda | DE |
JNO | Saltar si no hay desbordamiento | DE |
JP / JPE | Saltar paridad o saltar paridad par | PF |
JNP / JPO | Saltar sin paridad o Saltar con paridad impar | PF |
JS | Signo de salto (valor negativo) | SF |
JNS | Saltar sin signo (valor positivo) | SF |
La sintaxis para el conjunto de instrucciones J <condición> -
Ejemplo,
CMP AL, BL
JE EQUAL
CMP AL, BH
JE EQUAL
CMP AL, CL
JE EQUAL
NON_EQUAL: ...
EQUAL: ...
Ejemplo
El siguiente programa muestra la mayor de las tres variables. Las variables son variables de dos dígitos. Las tres variables num1, num2 y num3 tienen valores 47, 22 y 31, respectivamente -
section .text
global _start ;must be declared for using gcc
_start: ;tell linker entry point
mov ecx, [num1]
cmp ecx, [num2]
jg check_third_num
mov ecx, [num2]
check_third_num:
cmp ecx, [num3]
jg _exit
mov ecx, [num3]
_exit:
mov [largest], ecx
mov ecx,msg
mov edx, len
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
mov ecx,largest
mov edx, 2
mov ebx,1 ;file descriptor (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
mov eax, 1
int 80h
section .data
msg db "The largest digit is: ", 0xA,0xD
len equ $- msg
num1 dd '47'
num2 dd '22'
num3 dd '31'
segment .bss
largest resb 2
Cuando el código anterior se compila y ejecuta, produce el siguiente resultado:
The largest digit is:
47