Ciclos condicionales en ensamblador

Tabla de Contenido Introducción........................................................................................

Views 282 Downloads 1 File size 716KB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

Tabla de Contenido

Introducción.................................................................................................. 3 Desarrollo ..................................................................................................... 4 Marco Teórico ........................................................................................... 4 Instrucción LOOP ................................................................................... 4 Instrucciones LOOPZ y LOOPE............................................................ 6 Instrucciones LOOPNZ y LOOPNE ...................................................... 6 Ejemplo...................................................................................................... 7 Conclusión.................................................................................................... 9 Bibliografía ................................................................................................. 10

Tabla de Ilustraciones

Ilustración 1. Ejemplo de la instrucción LOOP ........................................... 7 Ilustración 2. Primera iteración de LOOP ................................................... 8 Ilustración 3. Segunda iteración de LOOP ................................................. 8 Ilustración 4. Finalización del ciclo LOOP .................................................. 9

Introducción En muchas ocasiones a la hora de programar es necesario ejecutar repetidas veces un conjunto de instrucciones; duplicar código parece una solución lógica cuando se está aprendiendo a programar, pero en realidad no es la más conveniente. Duplicar código puede acarrear varios problemas: lo primero es que se harán innecesariamente más extensos los archivos, en el caso de requerirse mantenimiento o actualización del código, será muy engorroso realizar este trabajo, además si el número de repeticiones es elevado haría prácticamente imposible cumplir con el cometido. Los ciclos o bucles permiten ejecutar repetidas veces una instrucción o un bloque de ellas; deben estar construidos de manera tal que se pueda tener control de la cantidad de repeticiones a realizar, de lo contrario se generaría un ciclo de ejecución infinita que podría desencadenar un desborde de memoria y en consecuencia un fallo de la aplicación, o un bloqueo de la misma porque el flujo de ejecución quedaría estancado en el ciclo, sobrecargando de tareas al procesador de la máquina que ejecuta el programa. Cuando el flujo de ejecución llega hasta la estructura cíclica, se examina si la condición declarada se cumple, de ser así se ejecuta el bloque de instrucciones contenido en el ciclo; este comportamiento se repite hasta que la condición deje de cumplirse, una vez no se cumpla la condición, el bloque de instrucciones es ‘ignorado’ y el flujo de ejecución se desplaza al final del ciclo, para continuar con las instrucciones siguientes.

3

Desarrollo Marco Teórico De manera predeterminada, la CPU carga y ejecuta los programas en forma secuencial. Pero la instrucción actual podría ser condicional, lo cual significa que transfiere el control a una nueva ubicación en el programa, con base en los valores de las banderas de estado de la CPU (Cero, Signo, Acarreo, etc.). Los programas en lenguaje

ensamblador

utilizan

instrucciones

condicionales

para

implementar

instrucciones de alto nivel, tales como las instrucciones IF y los ciclos. Cada una de las instrucciones condicionales implica una posible transferencia de control (salto) hacia una dirección de memoria distinta. Una transferencia de control, o bifurcación, es una manera de alterar el orden en el que se ejecutan las instrucciones. Hay dos tipos básicos de transferencias: 

Transferencia incondicional: en todos los casos el programa se transfiere (bifurca) hacia una nueva ubicación; se carga una nueva dirección de memoria en el apuntador de instrucciones, lo cual provoca que la ejecución continúe en la nueva dirección. La instrucción JMP es un buen ejemplo.



Transferencia condicional: el programa se bifurca si se cumple cierta condición. Puede combinarse una amplia variedad de instrucciones de transferencia condicional para crear estructuras lógicas condicionales. La CPU interpreta las condiciones de verdadero/falso de acuerdo con el contenido de los registros CX y Flags.

Instrucción LOOP Esta instrucción tiene el propósito de permitir que una rutina realice un ciclo un número específico de veces o hasta que se alcance una condición particular. La instrucción LOOP requiere un valor inicial en el registro CX. En cada iteración, LOOP de forma automática disminuye 1 de CX. Si el valor en CX es de cero, el control pasa a la instrucción que sigue; si el valor en el CX no es de cero, el control pasa a la dirección del operando. La distancia debe ser un salto corto, desde -128 hasta +127 bytes. Para 4

una operación que exceda este límite, el ensamblador envía un mensaje como “salto relativo fuera de rango”. (Peter Abel, 1966). La instrucción LOOP repite un bloque de instrucciones, un número específico de veces. CX se utiliza de manera automática como contador, y se decrementa cada vez que se repite el ciclo. Su sintaxis es: LOOP destino Para la ejecución de la instrucción LOOP se requieren dos pasos: primero, se resta 1 a CX. Después, CX se compara con cero. Si no es igual a cero, se realiza un salto hacia la etiqueta identificada por destino. En caso contrario, si CX es igual a cero, no se realiza ningún salto y el control pasa a la instrucción que sigue después del ciclo. En el siguiente ejemplo, sumamos 1 a AX cada vez que se repite el ciclo. Cuando termina el ciclo, AX igual 5 y CX igual a 0: mov ax,0 mov ecx,5 L1: inc ax loop L1 Un error común de programación es inicializar de manera inadvertida a CX con cero antes de empezar un ciclo. Si esto ocurre, la instrucción LOOP decrementa CX para que quede en FFFFFFFFh, ¡y el ciclo se repite 4,294,967,296 veces! Las instrucciones de máquina tienen un tamaño promedio aproximado de 3 bytes, por lo que un ciclo podría contener, en promedio, un máximo de 42 instrucciones. A continuación se muestra un ejemplo de un mensaje de error generado por MASM, debido a que la etiqueta de destino de una instrucción LOOP estaba demasiado alejada: (Irvine Kip R., 2008). error A2075: jump destination too far : by 14 byte(s)

5

Instrucciones LOOPZ y LOOPE La instrucción LOOPZ (salta si es cero) permite que un ciclo continúe mientras esté activa la bandera Cero y el valor sin signo de CX sea mayor que cero. La etiqueta de destino debe estar a una distancia entre -128 y +127 bytes de la ubicación de la siguiente instrucción. La sintaxis es: LOOPZ destino La instrucción LOOPE (itera si es igual) es equivalente a LOOPZ, ya que comparten el mismo código de operación. Realizan las siguientes tareas: CX = CX – 1 si CX > 0 y ZF = 1, saltar al destino En caso contrario, no se produce ningún salto y el control pasa a la sigui ente instrucción. LOOPZ y LOOPE no afectan a ninguna de las banderas de estado. (Irvine Kip R., 2008).

Instrucciones LOOPNZ y LOOPNE La instrucción LOOPNZ (salta si no es cero) es la contraparte de LOOPZ. El ciclo continúa mientras el valor sin signo de CX sea mayor que cero, y la bandera Cero esté en cero. La sintaxis es LOOPNZ destino La instrucción LOOPNE (salta si no es igual) es equivalente a LOOPNZ, ya que comparten el mismo código de operación. Estas instrucciones realizan las siguientes tareas: CX = ECX – 1 Si CX > 0 y ZF = 0, salta al destino En caso contrario, no ocurre nada y el control pasa a la siguiente instrucción. (Irvine Kip R., 2008).

6

Ejemplo El siguiente es un ejemplo simple en donde se utiliza la instrucción LOOP:

Ilustración 1. Ejemplo de la instrucción LOOP

Podemos destacar las siguientes cosas: 

Como siempre, comenzamos con la estructura básica de nuestro programa en las primeras 6 líneas y finalizando con la línea 22.



En la línea 07, se inicializa el registro CX con el valor de 5, es decir, el ciclo deberá de repetirse un total de 5 veces.



En la línea 09, declaramos el bloque de instrucciones que realizará cada ciclo, el cuál será imprimir una línea de texto en pantalla.



Al llegar a la línea 17, la instrucción LOOP hará que el flujo del programa regrese a la línea 09 que corresponde a “ciclo” y volverá a ejecutar sus instrucciones, no sin antes decrementar en 1 al registro CX.



El proceso anterior se repetirá hasta que el registro CX llegue a cero, provocando que no se realice la siguiente instrucción LOOP y el programa ejecute la línea 19.

7

Si ejecutamos nuestro código paso a paso, al momento que realiza el primer ciclo, es decir, la primera impresión del mensaje en pantalla, podemos observar que el valor del registro CX efectivamente decremento en 1, pues era de 5 originalmente y ahora es 4.

Ilustración 2. Primera iteración de LOOP

Ahora, si seguimos con nuestra ejecución paso a paso y llegamos a la parte en la que se imprime por segunda vez el mensaje en pantalla y revisamos nuestros registros, veremos que el de CX ha decrementado una vez más, en este caso ahora llegando al valor de 3, que sería el valor anterior de 4 menos 1.

Ilustración 3. Segunda iteración de LOOP

8

Si repetimos el proceso hasta que el programa de emu8086 nos diga que ha terminado la ejecución, podremos comprobar que efectivamente la cadena que declaramos se imprimió un total de 5 veces que fueron las que nosotros dijimos. Ahora, si volvemos a comprobar nuestros registros podremos ver que el de CX terminó llegando a 0, pues después de repetir el ciclo LOOP 5 veces, el número 5 fue disminuido en 1 esa misma cantidad de veces, llegando al 0, por lo que finalmente la condición para que el ciclo LOOP se repitiera ya no se cumplía.

Ilustración 4. Finalización del ciclo LOOP

Conclusión Creo que toda persona que haya usado cualquier lenguaje de programación se ha dado cuenta que los ciclos o bucles son una herramienta muy útil, que una vez que sabemos su funcionamientos queremos usarlo en todos los programas. Estos tipos de estructuras son sobretodo de mucha utilidad en el lenguaje ensamblador, ya que como es de nuestro conocimiento por ejemplos anteriores, se van ejecutando las líneas de código en el orden en que se escribieron, por lo que tener instrucciones que nos permitan repetir ciertas líneas las veces que queramos o dependiendo de la condición que nos permita el lenguaje, es de mucha utilidad para permitir que nuestros códigos no sean gigantescos. 9

Bibliografía 

Peter Abel, (1966). Lenguaje Ensamblador y programación para PC IBM y Compatibles, 3ª. Edición, Pearson Prentice Hall.



Kip R. Irvine, (2008). Lenguaje ensamblador para computadoras basadas en Intel, Pearson Prentice Hall, 5ª edición.



Badwin Arévalo Vera. (2017). Ciclos o Bucles - Nociones de programación. Obtenido

de:

https://www.bdwtown.com/blog/ciclos-o-bucles-nociones-de-

programacion_11.html 

Wikipedia. La enciclopedia libre. (2019). Bucle (programación). Obtenido de: https://es.wikipedia.org/wiki/Bucle_(programación)

10