jueves, 16 de abril de 2020

Unidad 3 – Modularización


3.1 Procedimientos

Un procedimiento es una secuencia de instrucciones que en conjunto llevan a cabo una tarea específica.

En programación un procedimiento es un segmento de código que cuenta con instrucciones a las cuales se puede acceder desde cualquier parte del programa y una vez se termina la ejecución de estas, el programa continua con su ejecución normal, tomando el control la siguiente línea después de la llamada al procedimiento. Los procedimientos tienden a ser grupos de instrucciones que se necesitara ejecutar más de una vez dentro de un programa, ya que un procedimiento puede ser llamado en cualquier momento durante la ejecución del programa principal, la cantidad de veces que sea necesario sin necesidad de reescribir el código.

En ensamblador los procedimientos están conformados por las siguientes partes:

Declaración del procedimiento:

Los procedimientos en ensamblador se declaran mediante la sintaxis nombreprocedimiento Proc [far/near] dependiendo de si es un procedimiento cercano o lejano.

Código del procedimiento:

Dentro del procedimiento se escribe el código de ensamblador que se quiere utilizar. 

Directiva de regreso:

Antes del final de un procedimiento en ensamblador se escribe la directiva de regreso ret,, la cual regresa el control a la línea desde donde fue llamado el procedimiento.

Terminación del procedimiento:

Para terminar un procedimiento se escribe el nombre del procedimiento seguido de la palabra reservaba endp.
Existen dos tipos de procedimientos que pueden utilizarse dentro de ensamblador, estos son los internos y los externos.

Procedimientos Internos:

Estos procedimientos son aquellos que son declarados dentro del mismo archivo de programa que serán llamados, también se les llama procedimientos locales.
Para utilizarlos basta con escribir la palabra reservada call seguida del nombre del procedimiento a utilizar.

Procedimientos Externos:

Los procedimientos externos se crean de la misma forma que los internos pero tienen la diferencia de que están en archivos separados al programa de donde el procedimiento es llamado, por lo que se necesitan instrucciones extra para poder utilizarlos, las cuales son las siguientes:

PUBLIC:

Es necesario declarar como publico el procedimiento que se desea utilizar para que sea posible acceder a él desde otro programa.

EXTRN:

Permite abrir procedimientos desde otro programa aunque no se encuentre enlazado directamente.

INCLUDE:

Enlaza el programa que llama el procedimiento con el que lo contiene, permitiendo utilizarlo como si fuera un procedimiento propio.

Ejemplo:



3.2 Macros.


 Una macro es un conjunto de instrucciones que pueden ser llamadas utilizando su nombre para ejecutarse dentro de un programa, estas solo se escriben una vez dentro del código y pueden utilizarse las veces que sea necesario.

En ensamblador la diferencia entre los procedimientos y las macros es que las macros tienen la posibilidad de utilizar parámetros por lo que pueden llevar a cabo tareas que los procedimientos no podrían.

Las macros constan de tres partes que las definen:

Declaración:

El inicio de una macro se declara escribiendo el nombre que tendrá, seguido de la palabra reservada MACRO y opcionalmente, puede contener parámetros después.

Cuerpo:

Contiene todas las instrucciones que ejecutara la macro cuando sea llamada dentro del programa en ejecución.

Fin:

Toda macro debe terminar con la palabra reservada ENDM para indicar el fin de esta.
Al igual que con los procedimientos, existen dos tipos de macros que son externas e internas, pero son muy fáciles de utilizar de cualquiera de las dos formas, si se desea utilizar una macro externa se escribe la palabra Include seguida del nombre del archivo de texto donde están guardadas las macros antes del código del programa.
Ejemplo:
Include Macro.txt                       →         Se enlaza con el archivo Macro.txt.

.model small                              →         Declaración del tamaño del programa.

.stack 64                                    →         Declaración de la pila.

.Data                                          →         Inicio del segmento de datos.

.Code                                         →         Inicio del segmento de código.

Macro1                                       →         Se llama a la macro Macro1.

.Exit                                            →         Inicio del segmento final.

End                                             →         Fin del programa.

miércoles, 15 de abril de 2020

Unidad 2 – Programación básica

2.1 Ensamblador (y ligador) a utilizar.

El término ensamblador se refiere a un tipo de programa informático que se encarga de traducir un fichero fuente escrito en un lenguaje ensamblador, a un fichero objeto que contiene código máquina, Ejecutable directamente por el microprocesador.

El programa lee el fichero escrito en el lenguaje ensamblador y sustituye cada uno d ellos códigos nemotécnicos que aparecen por su código de operación correspondiente en sistema binario para la plataforma que se eligió destino en las opciones específicas del ensamblador.

Podemos distinguir entre 2 tipos de ensambladores:

Ensambladores básicos: Son de muy bajo nivel, y su tarea consiste básicamente en ofrecer nombres simbólicos a las distintas instrucciones, parámetros y cosas tale como los modos.

Ensambladores modulares 32-bits o de alto nivel: Son ensambladores que aparecieron como respuesta a una nueva arquitectura de procesadores de 32 bits, muchos de ellos teniendo compatibilidad hacia atrás pudiendo trabajar con programas con estructura de 16 bits. Además de realizar la misma tarea que los anteriores, permitiendo también el uso de los macros, permiten utilizar estructuras de programación mas complejas propias de los lenguajes de alto nivel.

Un ligador, es un programa que enlaza todos los programas o módulos obteniendo lo que denominamos programa ejecutable.

Es un programa que enlaza distintos módulos o programas que poseen subprogramas. Además, incorporan las denominadas rutinas de librerías en caso de solicitarlas el propio programa. La generación de un modulo ejecutable a partir de una colección de procedimientos traducidos independientemente requiere un ligador.

Sus principales funciones:


Enlazar código intermedio compilado independientemente en un solo modulo de carga resolviendo las diferencias entre Tokens. Incorpora las denominadas rutinas de librerías en caso de solicitarlas el propio programa. Su función es reducir procedimientos traducidos por separado y enlazarlos para que se ejecuten como una unidad llamada programa binario ejecutable.

2.2 Ciclos numéricos.


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.

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.

Ejemplo:

·         ciclo: Etiqueta que se utilizará como referencia para el ciclo loopnz.
·         int 21h: Instrucción contenida dentro del ciclo.
·         loopnz: Ciclo loopnz 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.




2.3 Captura básica de cadenas.


Dentro del lenguaje ensamblador no existe el tipo de dato cadena (string en otros lenguajes), por lo que para utilizarla es necesario tratar a las cadenas como un conjunto de caracteres reservados bajo el nombre de una sola variable.

El lenguaje ensamblador cuenta con instrucciones que por su naturaleza sirven para el manejo de cadenas, estas son:

MOVSB:
Mueve un byte desde una localidad de memoria hasta otra.

MOVSW:
Mueve una palabra desde una localidad de memoria hasta otra.

LODSB:
Carga en la parte baja del registro acumulador (AL) el valor de la localidad de memoria determinada por DS:SI.

LODSW:
Carga en el registro acumulador (AX) el valor de la localidad de memoria determinada por DS:SI.

Ejemplo:



2.4 Comparación y prueba.


La comparación y prueba son instrucciones especiales con las que cuenta el microprocesador, estas son CMP y TEST respectivamente.

Comparación (CMP):

Esta instrucción compara los dos valores que se le den como parámetros y modifica las banderas de signo (SF), de cero (ZF) y de acarreo (CF) según sea necesario.

Ejemplo:

CMP ah,10h: Compara el valor almacenado en el registro ah con el valor 10 hexadecimal.

Prueba (TEST):

Verifica que los valores que se le introduzcan como parámetros sean iguales relizando la operación lógica AND, no almacena ningún resultado, pero modifica banderas según sea necesario.

Ejemplo:
TEST al, 1: Verifica que el valor almacenado en al sea 1.



2.5 Saltos


Los saltos son instrucciones que permiten al programador cambiar el orden de ejecución del programa según sea necesario, dentro de ensamblador existen dos tipos de salto principales: condicionales e incondicionales.

Saltos Incondicionales:

Los saltos incondicionales se utilizan mediante la instrucción JMP, la cual transfiere el control a la línea especificada después de la palabra JMP, la cual puede ser un valor directo o una etiqueta.

También se puede contar como un salto incondicional la instrucción CALL, la cual llama un procedimiento y al terminarla devuelve el control a la línea siguiente de donde se inició la llamada a procedimiento.

Ejemplo:

·         Salto: Etiqueta a la que se hará referencia para el salto incondicional.
·         JMP Salto: Instrucción que indica que el flujo del programa continuara desde la ubicación de la etiqueta Salto.

Saltos Condicionales:

Los saltos condicionales transfieren el control del programa a la ubicación que se les dé como parámetro si al hacer una comparación se cumple la condición establecida en el salto, los saltos condicionales son los siguientes:

JA (Jump if Above):
Salta cuando el valor es superior, su condición es equivalente al salto JNBE (Jump if Not Below or Equal).

JAE (Jump if Above or Equal):
Salta cuando el valor es superior o igual, su condición es equivalente al salto JNB (Jump if Not Below).

JB (Jump if Below):
Salta cuando el valor es menor, su condición es equivalente al salto JNAE (Jump if Not Above or Equal).

JBE (Jump if Below or Equal):
Salta cuando el valor es menor o igual, su condición es equivalente al salto JNA (Jump if Not Above).

JE (Jump if Equal):
Salta cuando el valor es igual.

JZ (Jump if Zero):
Salta cuando el valor es cero.

JNE (Jump if Not Equal):
Salta cuando el valor no es igual.

JNZ (Jump if Not Zero):
Salta cuando el valor no es cero.

JG (Jump if Greater):
Salta cuando el valor es mayor, su condición es equivalente al salto JNLE (Jump if Not Less or Equal).

JGE (Jump if Greater or Equal):
Salta cuando el valor es mayor o igual, su condición es equivalente al salto JNL (Jump if Not Less).

JL (Jump if Less):
Salta cuando el valor es menor, su condición es equivalente al salto JNGE (Jump if Not Greater or Equal).

JLE (Jump if Less or Equal):
Salta cuando el valor es menor o igual, su condición es equivalente al salto JNG (Jump if Not Greater).

Ejemplo:
·         Salto:  Etiqueta a la que se hará referencia para el salto condicional.
·         CMP al, bl: Comparación entre el valor almacenado en al y el almacenado en bl.
·         JG Salto: Instrucción que indica que el flujo del programa continuara desde la ubicación de la etiqueta Salto si el valor de la es mayor al de bl.