Tema III: Modularización - Axelrpg/Lenguajes-de-interfaz GitHub Wiki

3.1 Procedimientos

Un procedimiento es un conjunto de instrucciones que realizan una tarea específica y se pueden acceder desde cualquier parte del programa. Los procedimientos se usan para agrupar instrucciones que se ejecutan repetidamente en un programa y evitar tener que reescribir el mismo código una y otra vez.

Los procedimientos pueden ser de diferentes longitudes y complejidades, y un programa puede contener varios de ellos. Para utilizar un procedimiento, es necesario definirlo y llamarlo. Al definir el procedimiento, se escriben las instrucciones que realizarán la tarea específica. Luego, al llamar al procedimiento, se transferirá el control al conjunto de instrucciones del procedimiento para que se ejecuten.

En el lenguaje ensamblador, los procedimientos se componen de cuatro partes principales.

Declaración del procedimiento

La primera es la declaración del procedimiento, donde se especifica el nombre y si es cercano o lejano.

Codigo del procedimiento

La segunda parte es el código del procedimiento, que contiene las instrucciones que se quieren utilizar.

Directiva de regreso

Luego viene la directiva de regreso, que se utiliza antes del final del procedimiento y regresa el control a la línea desde donde fue llamado el procedimiento.

Terminación del procedimiento

Por último, se utiliza la palabra reservada "endp" para terminar el procedimiento.

El uso adecuado de estas partes es esencial para poder crear y utilizar procedimientos de manera efectiva en programas en ensamblador.

Tipos de procedimientos

Existen dos tipos de procedimientos en ensamblador: los internos y los externos.

Procedimientos internos

Los procedimientos internos, también conocidos como locales, son aquellos que se definen dentro del mismo archivo de programa que los llama. Para utilizarlos, se utiliza la instrucción "call" seguida del nombre del procedimiento deseado.

Procedimientos externos

Por otro lado, los procedimientos externos son aquellos que se encuentran en archivos separados al programa que los llama, lo que los hace un poco más complejos de utilizar. Para hacerlo, es necesario incluir algunas instrucciones adicionales en el código, que permiten al programa encontrar y utilizar el procedimiento externo.

Algunos ejemplos son los 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.

Un ejemplo en codigo:

public imprime → Procedimiento dentro del primero archivo declarado como publico.

imprime proc far → Declaracion del procedimiento.

mov ah,09h → Código del procedimiento

int 21h

ret → Directiva de regreso.

imprime endp → Fin del procedimiento.

extrn imprime:near → Se incluye el procedimiento externo imprime en el segundo archivo.

call imprime → Se llama al procedimiento como si fuera local.

3.2 - Macros

Una macro en ensamblador es un conjunto de instrucciones que se asocian a un nombre identificador. Al invocar la macro mediante su nombre, se ejecutan las instrucciones como una sola instrucción o macroinstrucción. La definición de la macro incluye su nombre, los parámetros que acepta y las instrucciones que contiene. A diferencia de los procedimientos, las macros pueden aceptar parámetros y se escriben una sola vez en el código, pudiendo ser utilizadas múltiples veces. En resumen, las macros son una herramienta útil en ensamblador para ejecutar tareas complejas y repetitivas de manera eficiente y con la posibilidad de personalizarlas mediante el uso de parámetros.

Una macro en ensamblador se divide en tres partes importantes: su declaración, su cuerpo y su finalización.

Declaración

En la declaración se define el nombre de la macro y, opcionalmente, los parámetros que pueda recibir.

Cuerpo

En el cuerpo es donde se escriben las instrucciones que ejecutará la macro cuando se llame desde el programa principal.

Fin

Finalmente, la macro debe ser cerrada con la palabra ENDM para indicar que ha terminado. Esto permite que se pueda utilizar la macro las veces que se necesite en el código, simplemente invocándola por su nombre y, en caso de ser necesario, pasando los parámetros correspondientes.

Al igual que los procedimientos, las macros también pueden ser externas o internas. Para utilizar una macro externa, simplemente se debe escribir la palabra "Include" seguida del nombre del archivo de texto donde se encuentran guardadas las macros, antes de escribir el código del programa que las va a utilizar. De esta manera, se pueden utilizar macros definidas en otros archivos sin tener que reescribir el código cada vez que se necesiten utilizar.

Por 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.

Práctica #1 - Operación lógica AND

Resumen

Este código realizará una operación que combina dos valores utilizando el operador AND. Luego, el resultado se convertirá en una cadena de caracteres utilizando el código ASCII correspondiente. Finalmente, se mostrará en la pantalla el mensaje "El resultado es: " seguido del valor del resultado.

Objetivo

Conocer y aplicar el funcionamiento de realizar operaciones lógicas para ayudar a resolver pequeñas problematicas con ayuda de ensamblador.

Introducción

Este es un ejemplo de programa en ensamblador que muestra cómo realizar una operación lógica y después imprimir el resultado en la pantalla. A pesar de que el lenguaje ensamblador puede parecer complejo, el código es en realidad sencillo y se divide en diferentes partes que establecen variables y constantes, y la sección principal donde se realiza la operación y se muestra el resultado. Conociendo cómo funciona la estructura del programa, es posible aplicar este conocimiento para resolver problemas similares en el futuro.

Metodología

image

Este programa escrito en lenguaje ensamblador realiza una operación AND entre los valores 2 y 1, y luego imprime el resultado en la consola. El programa tiene tres secciones: .data, .bss y .text. La sección .data se utiliza para definir variables y constantes, en este caso, la cadena de caracteres "El resultado es:" y algunos valores hexadecimales para dar formato a la impresión por pantalla. La sección .bss se utiliza para definir variables no inicializadas, en este caso, la variable resultado. La sección .text es donde se escribe el código principal del programa. El punto de inicio se indica con la directiva global _start.

En el código principal, primero se cargan los valores 2 y 1 en los registros al y bl, respectivamente. Luego se realiza la operación AND entre ambos valores utilizando la instrucción and al, bl. El resultado se almacena en la variable resultado, a la que se le agrega el valor ASCII del carácter '0'. Luego se utiliza la interrupción 0x80 del sistema operativo para imprimir la cadena "El resultado es:" por pantalla. Finalmente, se usa nuevamente la interrupción 0x80 para imprimir el valor almacenado en la variable resultado en la consola.

Resultados

image

Análisis

EL resultado se obtuvo sin dificultades. De esta manera vemos que con los conocimientos adquiridos hasta el momento, han sido de gran ayuda para entender cada vez más los siguientes problemas que se nos presenten.

Conclusiones

En resumen, el programa que se ha presentado es una muestra simple de cómo se puede escribir un código en lenguaje ensamblador para llevar a cabo una operación lógica y mostrar el resultado en la pantalla. A pesar de que el lenguaje ensamblador pueda parecer complejo, el programa es fácil de entender, y se compone de varias partes que definen variables y constantes, y la sección principal donde se realiza la operación y se muestra el resultado en la pantalla.

Referencias

Práctica #2 - Operación lógica OR

Resumen

El programa realiza una operación lógica OR entre dos valores, convierte el resultado a su representación ASCII y lo muestra por pantalla junto con una cadena de caracteres.

Objetivo

Conocer y aplicar el funcionamiento de realizar operaciones lógicas para ayudar a resolver pequeñas problematicas con ayuda de ensamblador.

Introducción

El código presentado es un programa en ensamblador que realiza la operación lógica OR entre dos valores y muestra el resultado en pantalla. Aunque pueda parecer complejo debido al lenguaje ensamblador, en realidad es un ejemplo sencillo que utiliza secciones para definir variables y constantes, y emplea conceptos básicos que se han aprendido en la materia.

Metodología

image

En la sección .data se define una cadena de caracteres que se imprimirá por pantalla junto a dos caracteres especiales que indican un salto de línea y un retorno de carro. La constante "lonmsg" se define como la longitud de esta cadena de caracteres. En la sección .bss se reserva un byte de memoria para almacenar el resultado de una operación. El código principal del programa se encuentra en la sección .text y comienza con la etiqueta "_start" que se marca como global. En este caso, el programa realiza la operación lógica OR entre los valores 2 y 1, convierte el resultado a su representación ASCII y lo almacena en la posición de memoria reservada en la sección .bss. Luego, se utiliza la interrupción del sistema operativo para imprimir la cadena de caracteres y el valor almacenado en la variable resultado por pantalla. Finalmente, el programa termina con la interrupción del sistema operativo para salir del programa. Esto se hace mediante la carga de los registros necesarios para realizar las interrupciones correspondientes.

Resultados

image

Análisis

Al igual que el código anterior, es una práctica sumamente sencilla de resolver. Por lo tanto, no requiere de mucha comprensión para llegar a intuir al resultado al que deberemos llegar al final de la práctica.

Conclusiones

A través de prácticas sencillas en lenguaje ensamblador, como la que se presenta en el código para realizar una operación lógica OR y mostrar el resultado, se pueden adquirir conocimientos sobre el uso de estas operaciones y cómo aplicarlas para resolver problemas simples. Es un buen punto de partida para aprender más sobre el lenguaje ensamblador y su uso en la programación de computadoras.

Referencias

Práctica #3 - Par o impar

Resumen

Este código es un ejemplo de un programa en lenguaje ensamblador que determina si un número es par o impar y muestra el resultado en la pantalla utilizando interrupciones del sistema operativo. Para hacerlo, utiliza la operación lógica AND para verificar si el número es divisible por dos y salta a diferentes etiquetas en función del resultado obtenido. En resumen, el programa es una demostración de cómo utilizar las operaciones lógicas en ensamblador para resolver un problema específico y mostrar el resultado utilizando las funciones del sistema operativo.

Objetivo

Aplicar conocimientos de saltos condicionales y de operaciones lógicas dando resolución a una pequeña problemática.

Introducción

En el lenguaje ensamblador, las operaciones lógicas se refieren al manejo de valores binarios o bits, que pueden representar valores booleanos como 0 y 1. Estas operaciones pueden ser muy útiles para resolver problemas simples, como determinar si un número es par o impar, y luego imprimir un mensaje que indique el resultado.

Metodología

image

El programa inicia definiendo dos mensajes de texto, "Es par" y "Es impar", cada uno seguido por los caracteres de nueva línea y retorno de carro. También se definen dos constantes que indican la longitud de cada mensaje. Luego, el programa entra en la sección del código principal, etiquetada como "_start". Aquí, se cargan los valores 7 y 1 en los registros al y bl, respectivamente.

El programa utiliza la operación lógica AND para determinar si el número en al es par o impar. Si el número es par, el resultado será cero, estableciendo la bandera de cero (ZF) en 1. Si el número es impar, el resultado será 1, estableciendo la bandera de cero en 0. Después, el programa usa la instrucción jz (jump if zero) para saltar a la etiqueta "espar" si la bandera de cero está establecida, lo que significa que el número es par. Si la bandera de cero no está establecida, el programa salta a la siguiente instrucción, que muestra el mensaje de texto "Es impar".

En la etiqueta "espar", el programa muestra el mensaje de texto "Es par" utilizando interrupciones del sistema operativo. Luego, el programa salta a la etiqueta "salir".

En la etiqueta "salir", el programa utiliza interrupciones del sistema operativo para salir del programa.

Resultados

image

Análisis

En esta práctica hacemos uso de conocimientos pasados y recientes para resolver esta problemática que no es muy difícil de analizar y comprender, obteniendo los resultados imaginados y dando cumplimiento al objetivo planteado al comienzo.

Conclusiones

En resumen, este programa práctico utiliza operaciones lógicas para determinar si un número es par o impar, y mostrar el resultado en la pantalla. Es un ejemplo claro de cómo las operaciones lógicas pueden ser útiles en la resolución de problemas. En el código, se utiliza la operación AND para verificar si el número es par o impar y luego se emplea la instrucción JZ (Jump if Zero) para saltar a diferentes etiquetas, según el resultado obtenido. Este programa ilustra cómo las operaciones lógicas pueden ser utilizadas en la programación para lograr ciertas tareas y solucionar problemas específicos.

Referencias

Practica #4 - If

Resumen

El siguiente código es un programa que compara dos números y muestra el resultado por pantalla. Este programa utiliza las operaciones básicas del lenguaje ensamblador, tales como mover valores de un lugar a otro (mov), comparar valores (cmp), saltar a una dirección de memoria específica si el resultado de la comparación es igual a cero (jz) o si no es cero (jnz), y realizar una interrupción en el sistema operativo para mostrar el resultado (int 0x80).

Objetivo

Conocer y aplicar las estructuras de control en lenguaje ensamblador de manera similar a como sucedería en otros lenguajes de programación.

Introducción

En programación, las estructuras de control son elementos clave que permiten dirigir el flujo de ejecución del programa. Con ellas, se pueden tomar decisiones, repetir bloques de código y desplazarse a diferentes partes del programa en función de determinadas condiciones. En este caso, nos centraremos en la estructura de control "IF".

Metodología

image

El código comienza con la definición de una variable llamada "resultado" de un byte de tamaño que se usará para almacenar el resultado de una comparación.

Luego, se declara la etiqueta _start como el punto de entrada del programa.

Las líneas mov eax, 5 y mov ebx, 9 asignan los valores 5 y 9 a las variables eax y ebx, respectivamente.

La línea cmp eax, 6 compara el valor de eax con 6. Si es igual, se salta a la etiqueta "funcionif", y si no es igual, se salta a la etiqueta "funcionelse".

La etiqueta "funcionif" mueve el valor 1 a la variable ebx, mientras que la etiqueta "funcionelse" mueve el valor 0 a la variable ebx.

La etiqueta "salir" agrega 48 al valor de ebx para convertirlo en el código ASCII correspondiente al número, y luego mueve el valor de ebx a la variable resultado.

Para imprimir el valor de la variable resultado en la consola, se utilizan las llamadas al sistema int 0x80. Primero, se asignan los valores 4 y 1 a eax y ebx, respectivamente, para indicar que se escribirá en la consola. Luego, se asignan el valor de resultado a ecx y el valor 1 a edx para indicar la longitud de los datos a escribir (1 byte).

Por último, se utiliza la llamada al sistema int 0x80 para salir del programa, con eax establecido en 1 para indicar que el programa se está cerrando y ebx establecido en 0 para indicar que no se produjo un error.

Resultados

image

Análisis

Aplicar los conocimientos para resolver esta pequeña problemática fue muy sencilla, logrando cumplir el objetivo y obteniendo los resultados esperados satisfactoriamente.

Conclusiones

El siguiente programa es un ejemplo de cómo se puede utilizar el lenguaje ensamblador para realizar operaciones aritméticas y utilizar la estructura de control "IF". Aunque es un programa simple, demuestra cómo se pueden utilizar estas herramientas de bajo nivel para resolver problemas específicos y cómo se pueden aplicar en el desarrollo de aplicaciones de sistemas operativos de bajo nivel.

Referencias

¿Cómo hacer un IF en assembler? (s. f.). https://www.todopic.com.ar/foros/index.php?topic=15674.0

Practica #5 - For

Resumen

El siguiente código es un ejemplo de cómo se puede utilizar un bucle for para realizar operaciones aritméticas simples y mostrar los resultados por pantalla. El programa utiliza una combinación de instrucciones básicas de ensamblador y llamadas al sistema para realizar estas operaciones y luego imprimir el resultado en la consola. A través del uso de instrucciones como mov, and, sub y add, se llevan a cabo las operaciones aritméticas necesarias para obtener una suma al final del proceso.

Objetivo

Conocer y aplicar las estructuras de control en lenguaje ensamblador de manera similar a como sucedería en otros lenguajes de programación.

Introducción

Las estructuras de control son mecanismos esenciales en la programación, ya que permiten controlar la manera en que un programa se ejecuta. Estas estructuras facilitan la toma de decisiones, la repetición de bloques de código y la capacidad de saltar a diferentes secciones del programa en función de ciertas condiciones. En esta ocasión, se abordará específicamente la estructura de control "For".

Metodología

image

Este programa es un bucle que suma los números impares del 1 al 3n, donde n es un valor dado por el usuario.

Primero se define una sección .bss donde se reserva un byte para almacenar el resultado de la suma de los números impares. Luego, se define la sección .text, donde se declara la etiqueta _start como el punto de entrada del programa.

En la etiqueta _start se inicializan los registros eax, ebx, y edx con los valores 0, 1 y 0, respectivamente. Se utiliza un bucle for para iterar desde 3 hasta 3n, donde n es un valor dado por el usuario y se almacena en el registro ecx.

Dentro del bucle, se duplica el valor del contador de ciclo (que se almacena en edx) y se utiliza la operación AND con el valor 1 para determinar si es impar. Si el resultado es 1, se salta a la etiqueta "impar". De lo contrario, se continúa con el ciclo.

En la etiqueta "impar", se suma el valor del ciclo actual (almacenado en ecx) a la variable acumuladora (almacenada en eax). Luego, se continúa con el ciclo.

Después de que se completa el ciclo, se agrega 48 al valor de la variable acumuladora (para convertirla en el código ASCII correspondiente al número) y se mueve el resultado a la variable "resultado". Luego, se utilizan las interrupciones del sistema operativo para imprimir el valor de la variable resultado en la consola.

Finalmente, se utiliza la interrupción del sistema operativo int 0x80 nuevamente para salir del programa. eax se establece en 1 para indicar que el programa se está cerrando y ebx se establece en 0 para indicar que no se produjo un error.

Resultados

image

Análisis

Conocer más acerca de este tema resulta sencillo en la teoría y en la práctica, por lo que, los resultados esperados y obtenidos fueron exitosos.

Conclusiones

En resumen, el código que utiliza operaciones aritméticas y estructuras de control como el bucle for es un ejemplo eficaz de cómo se puede tener un mayor control sobre el hardware y la memoria del sistema mediante el lenguaje ensamblador. Aunque pueda resultar complicado para aquellos no familiarizados con el lenguaje, ofrece un mayor rendimiento y eficiencia en aplicaciones de bajo nivel. Con los conocimientos básicos que se han adquirido hasta el momento, se puede comprender el tema con facilidad.

Referencias

¿Cómo hacer un FOR en ensamblador? (s. f.). https://www.todopic.com.ar/foros/index.php?topic=14625.0

Practica #6 - Procedimiento

Resumen

En esta práctica se verá el funcionamiento de los procedimientos en ensamblador, realizando la impresión de un mensaje para notar su influencia en el flujo de ejecución del código y cómo puede ayudarnos a reutilizar código o evitar tener que escribir código repetitivo.

Objetivo

Conocer el funcionamiento de los Procedimientos en NASM y aplicarlos en la resolución de una problemática.

Introducción

Los procedimientos son fragmentos de código que se encargan de realizar una tarea específica y se utilizan para dividir programas más grandes en partes más manejables y reutilizables. Son una herramienta útil para hacer que los programas sean más modulares y fáciles de mantener, ya que se pueden definir una vez y utilizar en diferentes partes del programa. Además, los procedimientos hacen que el código sea más fácil de leer y entender, ya que las partes repetitivas se pueden encapsular en procedimientos con nombres descriptivos.

Metodología

image

En el programa, primero se definen dos mensajes utilizando la sección .data. Cada mensaje se termina con un carácter de nueva línea y de retorno de carro, y se establece un byte final en cero para indicar el final del mensaje. La longitud de cada mensaje se calcula utilizando la directiva equ y la etiqueta $.

En la sección .text, se define una etiqueta llamada "imprime", que se utiliza para imprimir en la consola utilizando la llamada al sistema write y la interrupción 0x80 del kernel de Linux. La instrucción "ret" se utiliza para devolver el control al llamador.

En la etiqueta _start, se carga la dirección de msg1 en el registro ecx y la longitud de msg1 en edx. Luego se llama a la etiqueta imprime para imprimir el mensaje msg1. Después, se carga el valor 1 en el registro eax para indicar la llamada al sistema exit. El valor 0 se carga en el registro ebx y se realiza una interrupción 0x80 para salir del programa. En resumen, este programa imprime un mensaje en la consola y luego sale del programa.

Resultados

image

Análisis

Obtener el resultado final con el esperado fue sencillo, logrando imprimir un mensaje para dar muestra del funcionamiento de los Procedimientos en NASM.

Conclusiones

Los procedimientos son una herramienta importante en la programación, ya que permiten escribir bloques de código que realizan una tarea específica y reutilizarlos en diferentes partes del programa. Esto hace que el código sea más fácil de entender y mantener, ya que los bloques de código repetitivos pueden ser encapsulados en procedimientos con nombres descriptivos. Además, el uso de procedimientos hace que los programas sean más modulares y legibles, lo que mejora su calidad y eficiencia en general. En resumen, el uso de procedimientos puede ahorrar tiempo y esfuerzo en la programación y mejorar la calidad del código.

Referencias

Práctica #7 - Macro

Resumen

Este código muestra cómo imprimir mensajes en la consola utilizando las llamadas al sistema proporcionadas por el sistema operativo. También se utiliza una macro definida por el usuario para simplificar la impresión de mensajes en la consola.

Objetivo

Conocer y aplicar los Macros en NASM facilitando la impresión de mensajes.

Introducción

Los macros son una funcionalidad esencial en la programación en ensamblador que permite definir código que se puede reutilizar. Un macro es un bloque de instrucciones que se pueden definir en una sola línea y se pueden llamar varias veces en diferentes partes del programa. Se pueden utilizar para agrupar instrucciones que se repiten con frecuencia o para definir instrucciones personalizadas que no se encuentran en la lista de instrucciones nativas.

Metodología

image

En el código presentado se define una macro llamada "imprime" que simplifica la tarea de imprimir mensajes en la consola. Esta macro recibe dos argumentos: el mensaje que se desea imprimir y la longitud del mensaje. La macro utiliza una llamada al sistema write, pero su funcionamiento se simplifica mediante la agrupación de las instrucciones en una sola línea de código. Esto permite llamar a la macro "imprime" cada vez que se quiera imprimir un mensaje, evitando tener que escribir la llamada al sistema write cada vez.

En la sección .data se define el mensaje y su longitud correspondiente. Los caracteres de salto de línea y retorno de carro se representan mediante los códigos ASCII 10 y 13, respectivamente.

En la sección .text, la macro "imprime" se utiliza para imprimir el mensaje definido anteriormente, pasando los argumentos necesarios a la macro. Finalmente, el programa finaliza su ejecución utilizando la llamada al sistema exit.

Resultados

image

Análisis

Los resultados fueron satisfactorios y se da cumplimiento al objetivo de la práctica.

Conclusiones

Los macros son una herramienta muy útil que permiten simplificar la escritura de código y aumentar la legibilidad y mantenibilidad del mismo. Al definir una serie de instrucciones que se pueden llamar múltiples veces, los macros eliminan la necesidad de escribir código repetitivo y reducen la cantidad de líneas de código que deben ser escritas manualmente.

Referencias