martes, 17 de marzo de 2020

2.2 Ciclos numéricos

Ciclos numéricos

La arquitectura de los procesadores x86 obliga al uso de segmentos de memoria para manejar la información, el tamaño de estos segmentos es de 64kb. 

La razón de ser de estos segmentos es que, considerando que el tamaño máximo de un número que puede manejar el procesador esta dado por una palabra de 16 bits o registro, no sería posible acceder a más de 65536 localidades de memoria utilizando uno solo de estos registros, ahora, si se divide la memoria de la pc en grupos o segmentos, cada uno de 65536 localidades, y utilizamos una dirección en un registro exclusivo para localizar cada segmento, y entonces cada dirección de una casilla específica la formamos con dos registros, nos es posible acceder a una cantidad de 4294967296 bytes de memoria, lo cual es, en la actualidad, más memoria de la que veremos instalada en una PC. 

Para que el ensamblador pueda manejar los datos es necesario que cada dato o instrucción se encuentren localizados en el área que corresponde a sus respectivos segmentos. El ensamblador accede a esta información tomando en cuenta la localización del segmento, dada por los registros DS, ES, SS y CS, y dentro de dicho registro la dirección del dato específico.


Saltos, ciclos y procedimientos.

Los saltos incondicionales en un programa escrito en lenguaje ensamblador están dados por la instrucción jmp, un salto es alterar el flujo de la ejecución de un programa enviando el control a la dirección indicada.

Un ciclo, conocido también como iteración, es la repetición de un proceso un cierto número de veces hasta que alguna condición se cumpla. En estos ciclos se utilizan los brincos "condicionales" basados en el estado de las banderas. Por ejemplo la instrucción jnz que salta solamente si el resultado de una operación es diferente de cero y la instrucción jz que salta si el resultado de la operación es cero.
Por último tenemos los procedimientos o rutinas, que son una serie de pasos que se usarán repetidamente en el programa y en lugar de escribir todo el conjunto de pasos únicamente se les llama por medio de la instrucción call.

Un procedimiento en ensamblador es aquel que inicie con la palabra Proc y termine con la palabra ret. Realmente lo que sucede con el uso de la instrucción call es que se guarda en la pila el registro IP y se carga la dirección del procedimiento en el mismo registro, conociendo que IP contiene la localización de la siguiente instrucción que ejecutara la UCP, entonces podemos darnos cuenta que se desvía el flujo del programa hacia la dirección especificada en este registro. Al momento en que se llega a la palabra ret se saca de la pila el valor de IP con lo que se devuelve el control al punto del programa donde se invocó al procedimiento. Es posible llamar a un procedimiento que se encuentre ubicado en otro segmento, para ésto el contenido de CS (que nos indica que segmento se está utilizando) es empujado también en la pila.

Como en cualquier otro lenguaje de programación, hay ocasiones en las que es necesario hacer que el programa no siga una secuencia lineal, sino que repita varias veces una misma instrucción o bloque de instrucciones antes de continuar con el resto del programa, es para esto que se utilizan los ciclos.

Existen 5 tipos de ciclos predefinidos en ensamblador, aunque también se pueden crear ciclos personalizados por medio de instrucciones de salto las cuales se verán en la sección 2.6 de este manual.

Los ciclos predefinidos de ensamblador son los siguientes:

LOOP:

Esta función decrementa el valor del registro contador CX, si el valor contenido en CX es cero ejecuta la siguiente instrucción, en caso contrario transfiere el control a la ubicación definida por la etiqueta utilizada al momento de declarar el ciclo.

Ejemplo:

mov cx,25 :    Número de veces que se repetirá el ciclo, en este caso 25.
ciclo:  Etiqueta que se utilizará como referencia para el ciclo loop.
int 21h: Instrucción contenida dentro del ciclo (puede contener más de una instrucción).
loop:  Ciclo loop que transferirá el control a la línea de la etiqueta ciclo en caso de que CX no sea cero.

LOOPE:

Esta función decrementa el valor del registro contador CX, si el valor contenido en CX es cero y ZF es diferente de uno ejecuta la siguiente instrucción, en caso contrario transfiere el control a la ubicación definida por la etiqueta utilizada al momento de declarar el ciclo.

Ejemplo:

ciclo: Etiqueta que se utilizará como referencia para el ciclo loope.
int 21h: Instrucción contenida dentro del ciclo (puede contener más de una instrucción).
loope: Ciclo loope que transferirá el control a la línea de la etiqueta ciclo en caso de que CX no sea cero y ZF sea igual a uno.

LOOPNE:

Esta función decrementa el valor del registro contador CX, si el valor contenido en CX es cero y ZF es diferente de cero ejecuta la siguiente instrucción, en caso contrario transfiere el control a la ubicación definida por la etiqueta utilizada al momento de declarar el ciclo, esta es la operación contraria a loope.

Ejemplo:
  • ciclo: Etiqueta que se utilizará como referencia para el ciclo loopne.
  • int 21h: Instrucción contenida dentro del ciclo (puede contener más de una instrucción).
  • loopne: Ciclo loopne que transferirá el control a la línea de la etiqueta ciclo en caso de que CX no sea cero y ZF sea igual a cero.
LOOPZ:

Esta función decrementa el valor del registro contador CX, si el valor contenido en CX es cero y ZF es diferente de uno ejecuta la siguiente instrucción, en caso contrario transfiere el control a la ubicación definida por la etiqueta utilizada al momento de declarar el ciclo.

Ejemplo:

  • ciclo: Etiqueta que se utilizará como referencia para el ciclo loopz.
  • int 21h: Instrucción contenida dentro del ciclo (puede contener más de una instrucción).
  • loopz: Ciclo loopz que transferirá el control a la línea de la etiqueta ciclo en caso de que CX no sea cero y ZF sea igual a uno.
LOOPNZ:

Esta función decrementa el valor del registro contador CX, si el valor contenido en CX es cero y ZF es diferente de cero ejecuta la siguiente instrucción, en caso contrario transfiere el control a la ubicación definida por la etiqueta utilizada al momento de declarar el ciclo, esta es la operación contraria a loopz.

Resultado de imagen para ciclos numéricos.










No hay comentarios.:

Publicar un comentario