Tema II Prácticas - Crypto-ch4r/Lenguajes-de-Interfaz- GitHub Wiki

Prácticas unidad II

Práctica #1: Medio sumador en Minecraft utilizando compuertas lógicas básicas

Resumen

Se realizó un medio sumador simulando compuertas lógicas en Minecraft con redstone y antorchas del mismo material y comprobando su funcionamiento con una tabla de verdad.

Objetivo

El objetivo de esta práctica es conocer el funcionamiento de las compuertas lógicas construyendo un medio sumador en Minecraft.

Introducción

Un medio sumador es un tipo de sumador, un circuito electrónico que realiza la suma de números. La mitad del sumador es capaz de sumar dos dígitos binarios simples y proporcionar el resultado más un valor de acarreo. Tiene dos entradas, llamadas A y B, y dos salidas S (sum) y C (carry). La representación común utiliza una puerta lógica XOR y una puerta lógica AND. Para comprender mejor su funcionamiento, en la presente practica se construirá el medio sumador utilizando componentes de Minecraft para simular las compuertas y salidas de este circuito.

Metodología

Compuerta XOR

Compuerta AND

Materiales y componentes utilizados:

  • Polvo de redstone, repetidores de redstone y antochas de redstone.
  • Dos palancas.
  • Bloques de cualquier tipo.
  • 1 compuerta XOR
  • 1 compuerta AND.

Una vez construidas las compuertas utilizando los materiales y componentes que involucran al redstone, nos apoyamos con las palancas para simular la entrada de 1's y 0's en nuestro medio sumador. Al ir introduciendo estos valores podremos ver las salidas como "sum" y "carry" al ver la reacción en los componentes utilizados como salidas (un pistón y lámparas de redstone en este caso). Siguiendo la guía de la tabla de verdad en la siguiente imagen, el pistón se activará cuando se introduzca POR LO MENOS un 1 en las entradas del sumador. Por otro lado, la lampara de redstone se activara SOLAMENTE si se introducen dos 1's en ambas entradas del sistema, de lo contrario no encenderá. Si tenemos dos 0's como entrada ninguna de las salidas mostrará cambios. Su explicación es bastante sencilla guiándonos con la tabla de verdad, para analizar más a fondo el funcionamiento puedes checar el vídeo explicativo anexado en las referencias de esta práctica.

Resultados

Análisis

La práctica resulto ser exitosa al comprobar su correcto funcionamiento con la tabla de verdad perteneciente al medio sumador. Por ende, se puede afirmar que se aplicaron de correctamente las compuertas lógicas.

Conclusiones

Fue una práctica de lo más interesante al simular circuitos electrónicos en un sistema como lo es Minecraft, de esta forma y en mi opinión personal, se comprende un poco mejor el funcionamiento de estos componentes que muchas veces suele ser complicado de comprender viéndolos solo de forma teórica. Esta práctica tuvo cierto grado de complejidad ya que anteriormente no había usado redstone para cosas tan complejas pero fue bastante divertida de realizar.

Referencias

Práctica #2: Hola mundo en Ensamblador

Resumen

En esta práctica se ve más a fondo el funcionamiento del programa "Hola mundo" en Ensamblador, analizando línea por línea del código para comprender los muchos porques del código.

Objetivo

El objetivo de esta práctica es cómo funcionan los registros y demás comandos básicos del lenguaje ensamblador utilizando un "Hola mundo".

Introducción

En el desarrollo de esta práctica número 2 analizaremos a fondo el funcionamiento de la sintaxis básica del lenguaje Ensamblador haciendo un programa que imprima "Hola mundo" en la pantalla de la computadora. Se verán a fondo los registros que se utilizaran para la realización de la misma y el significado de varias instrucciones o líneas completas del programa.

Metodologia

section .data

Esta sección es la primera en cualquier programa en Ensamblador, en ella se definen los datos a utilizar al igual que las variables. En este caso estamos declarando una cadena de caracteres "msg" que contiene el mensaje y un carácter de nueva línea "\n" (salto de línea). La instrucción "len equ $ - msg" define la longitud de la cadena como la dirección actual menos la dirección de la cadena, lo que significa que "len" tendrá el valor de la longitud de la cadena "msg".

section .text

En esta sección declaramos el código principal del programa, básicamente en esta sección es donde llevamos a cabo todas las operaciones que realizara el programa (siendo una impresión en pantalla en este caso). La instrucción "global _start" indica que la etiqueta "_start" es el punto de entrada del programa. La etiqueta "_start" comienza con tres instrucciones "mov" que establecen los valores de los registros "edx", "ecx" y "ebx". El registro "edx" se establece en "len", que es la longitud de la cadena de caracteres "msg". El registro "ecx" se establece en "msg", que es la dirección de la cadena de caracteres "msg". Y el registro "ebx" se establece en 1, que indica la salida estándar.

La siguiente instrucción "mov eax,4" establece el valor del registro "eax" en 4, que indica la llamada del sistema "write". La instrucción "int 0x80" hace la llamada al sistema para escribir la cadena en la salida estándar. La última instrucción "mov eax,1" establece el valor del registro "eax" en 1, que indica la llamada del sistema "exit". La instrucción "int 0x80" hace la llamada al sistema para salir del programa terminando con la ejecución del mismo.

Resultados

Análisis

Obtuvimos como resultado el tan esperado y clásico "hola mundo" impreso en el monitor así como también hemos podido comprender un poco mejor como es que funcionan los registros.

Conclusiones

Durante el desarrollo de esta práctica hemos podido reforzar los conocimientos previos que teníamos sobre el lenguaje Ensamblador gracias a una explicación detallada y documentación de la misma. Como se mencionó en el análisis, se ha podido comprender un poco mejor los registros que usa Ensamblador así como también la importancia de ciertas líneas como es la línea para la salida del programa.

Referencias

Práctica #3: Suma en Ensamblador

Resumen

En esta práctica se realizó la suma de dos números haciendo uso de la instrucción add perteneciente al lenguaje Ensamblador como parte de las operaciones aritméticas básicas.

Objetivo

Conocer el comando add y ver más a profundidad como realizar operaciones matemáticas en Ensamblador obteniendo la suma de dos números enteros almacenados en registros.

Introducción

Esta es la primera práctica a realizar haciendo uso de las operaciones aritméticas básicas, para esta práctica se comenzara con la operación de suma en la cual como resultado debemos de obtener la suma correcta de dos números almacenados en los registros de la computadora.

Metodología

Section .data

Como en prácticas anteriores en esta sección declaramos nuestras variables y datos a utilizar durante la ejecución. Para esta práctica solo vamos a definir la variable "resultado" y le asignamos el tamaño de un byte con "db" y la inicializamos en cero. Seguido de esto el salto de línea.

Section .text

Como se ha dicho anteriormente en otras prácticas, esta sección contiene en código principal del programa. Aquí vamos a definir la función _start para definir el punto de entrada al programa. Seguido de esto, asignamos en los registros eax y ebx los valores 2 y 3 que son los números a sumar para esta práctica. Después de esto, hacemos uso de add para sumar los valores de ambos registros mencionados y lo almacenamos en eax. Acto seguido hacemos uso de la función add para sumar un 48 al número resultante de la suma, esto para que corresponda al valor ASCII correspondiente a la suma de esos dos números.

Almacenamos todo en la variable resultado y haciendo uso del número 4 llamamos a la función write del sistema para imprimir el resultado, con el 1 llamamos a la función exit y finalmente int 0x80 para invocar la interrupción en el sistema y llamar a la función de escribir. Terminamos el programa con la función exit para finalizarlo y cargamos antes de salir los valores 1 y 0 en los registros eax y ebx

Resultados

Como resultado obtenemos un 5 en la consola por lo que podemos decir que se logró llegar al resultado esperado.

Análisis

Al obtener los resultados esperados, podemos decir que la práctica resultó ser todo un éxito. Aunque la complejidad aumento bastante al querer realizar una suma de dos dígitos.

Conclusiones

Hacer una suma de números de un solo digito en Ensamblador resulto ser una tarea sencilla, no obstante la complejidad aumenta bastante al involucrar sumas de números de más de un digito así como también resultados de dos dígitos debido a que la tabla de símbolos ASCII solo tiene los números del 0 al 9 y por ende para mostrar números de dos dígitos lo más probable es que requiera de una concatenación.

Referencias

Práctica #4: Resta en Ensamblador

Resumen

En esta práctica se realizó la resta de dos números haciendo uso de la instrucción sub perteneciente al lenguaje Ensamblador como parte de las operaciones aritméticas básicas.

Objetivo

Conocer el comando sub y ver más a profundidad como realizar operaciones matemáticas en Ensamblador obteniendo la suma de dos números enteros almacenados en registros.

Introducción

Esta es la segunda práctica a realizar haciendo uso de las operaciones aritméticas básicas, para esta práctica vamos a realizar la resta entre dos números de un digito, positivos y enteros en la cual como resultado debemos de obtener la resta correcta de dos números almacenados en los registros de la computadora.

Metodología

Section .data

Declaramos nuestras variables y datos a utilizar durante la ejecución. Para esta práctica solo vamos a definir la variable "resultado" como una cadena de caracteres para almacenar un texto.

Section .text

Definimos la función _start para definir el punto de entrada al programa. Seguido de esto, movemos a los registros ebx y eax los valores 8 y 5 que son los números a restar para esta práctica. Después de esto, hacemos uso de sub para hacer la operación aritmética entre los valores de ambos registros mencionados y almacenamos el resultado. Acto seguido hacemos uso de la función add para sumar un 48 al número resultante de la resta, para que corresponda al valor ASCII correspondiente a la resta de esos dos números.

Almacenamos todo en la variable resultado y haciendo uso del número 4 llamamos a la función write del sistema para imprimir el resultado, con el 1 llamamos a la función exit y finalmente int 0x80 para invocar la interrupción en el sistema y llamar a la función de escribir. Terminamos el programa con la función exit para finalizarlo y cargamos antes de salir los valores 1 y 0 en los registros eax y ebx

Resultados

Como resultado obtenemos un 3 impreso en la consola del sistema por lo que podemos decir que se ha obtenido el resultado esperado de manera exitosa.

Análisis

La práctica se concluyó de manera exitosa, no obstante hubieron algunas complicaciones al querer restar de forma que el resultado sea un número negativo y se pudo notar que el grado de complejidad se elevó bastante.

Conclusiones

A medida que avanzamos con las prácticas de operaciones aritméticas básicas, podemos darnos cuenta de que el lenguaje Ensamblador es un lenguaje MUY diferente a los lenguajes de programación de alto nivel a los que estamos acostumbrados muchos desde que tomamos programación en el bachillerato ya que en un lenguaje de alto nivel como lo es Java es bastante sencillo conseguir números negativos, sumar números de más de un digito, etcétera.

Referencias

Assembly - Arithmetic Instructions. (s. f.). https://www.tutorialspoint.com/assembly_programming/assembly_arithmetic_instructions.htm

Práctica #5: Multiplicación en Ensamblador

Resumen

En esta práctica nuevamente empleamos operadores aritméticos básicos para realizar operaciones matemáticas siendo en este caso una multiplicación entre dos números con apoyo de la función mul

Objetivo

Conocer el comando mul y ver más a profundidad como realizar operaciones matemáticas en Ensamblador.

Metodología

Section .data

Al igual que en otras prácticas, comenzamos definiendo la variable en la que se va a almacenar nuestro resultado reservando un byte de memoria para el mismo con la palabra resb

Section .text

Definimos la función _start para definir el punto de entrada al programa. Seguido de esto, asignamos en los registros ax y cx los valores 3 y 2 que son los números a multiplicar para esta práctica. Después de esto, hacemos uso de mul para realizar la multiplicación de los valores de ambos registros mencionados y lo almacenamos en ax. Acto seguido uso nuevamente de la función add para sumar un 48 al número resultante de la operación, para que corresponda al valor ASCII correspondiente a la resta de esos dos números.

Almacenamos todo en la variable resultado y haciendo uso del número 4 llamamos a la función write del sistema para imprimir el resultado, con el 1 llamamos a la función exit y finalmente int 0x80 para invocar la interrupción en el sistema y llamar a la función de escribir. Terminamos el programa con la función exit para finalizarlo y cargamos antes de salir los valores 1 y 0 en los registros eax y ebx

Resultados

Como resultado obtenemos un 6 impreso en la consola del sistema, por lo que podemos decir que hemos llegado al resultado esperado.

  • :warning: NOTA: Se intentaron diversos métodos para conseguir un salto de línea, sin embargo al momento de ensamblar el código este fallaba debido a errores por esas modificaciones. Al final se optó por dejarlo pues la practica al final de cuentas cumple su cometido al lograr la multiplicación entre dos números.

Análisis

Realizar esta práctica fue relativamente sencilla ya que no requirió de romperse mucho la cabeza una vez que conoces las funciones y algo de sintaxis para mover los valores entre registros, etc.

Conclusiones

A pesar de que fue una práctica relativamente sencilla, lo más probable es que aumente su dificultad al querer agregar números de más de un digito como se ha visto en prácticas previas durante esta segunda unidad.

Referencias

Assembly - Arithmetic Instructions. (s. f.). https://www.tutorialspoint.com/assembly_programming/assembly_arithmetic_instructions.htm

Práctica #6: División en Ensamblador

Resumen

En esta práctica nuevamente empleamos operadores aritméticos para realizar operaciones matemáticas siendo en este caso una división entre dos números.

Objetivo

Conocer el comando div y ver más a profundidad como realizar operaciones matemáticas en Ensamblador.

Introducción

En esta práctica realizaremos un programa en Ensamblador que sea capaz de dividir dos números entre si e imprimiendo su resultado en la consola.

Metodología

NOTA: Usamos .bss para reservar un byte en memoria para dicha variable. Empezamos declarando la variable que almacenara el resultado a imprimir. En la sección principal (.text) del código vamos a declarar nuestro punto de entrada _start comenzando con instrucciones mov para inicializar los registros bx, dx y y ax con los valores 2, 0 y 8 como se puede apreciar en el código de arriba.

  • :warning: NOTA: Al asignarle un 0 al registro dx, este se borra. Acto seguido, hacemos llamada a la función div para realizar la división entre los valores almacenados en ax y bx siendo 8 y 4 respectivamente dando como resultado un 4 siendo este último almacenado en ax. Después de la división sumamos 48 al resultado para que este equivalga a su representación ASCII correcta, si omitiéramos esta suma la consola imprimiría un valor completamente diferente.

Después con otra instrucción mov movemos nuestro resultado del registro ax a la variable correspondiente que en este caso sería resultado. Finalmente se hacen las interrupciones del sistema necesarias para imprimir el resultado en consola y finalmente finalizar la ejecución del programa.

Resultados

  • :warning: NOTA: Se intentaron diversos métodos para conseguir un salto de línea, sin embargo al momento de ensamblar el código este fallaba debido a errores por esas modificaciones. Al final se optó por dejarlo pues la practica al final de cuentas cumple su cometido al lograr la división entre dos números.

Análisis

El resultado fue justamente lo que se esperaba, un 4 en la consola. La practica la única complicación que tuvo fue la ausencia del salto de línea.

Conclusiones

Fue una práctica sencilla de realizar, dividir un numero entero entre otro y que dé como resultado un numero entero no fue mucha ciencia. Por otro lado, el salto de línea si dio algunas complicaciones y se sigue buscando alguna solución para poder lograrlo sin que truene el programa, no obstante, en lo personal creo que se cumplió el objetivo de la práctica.

Referencias

Práctica #7: Desplazamiento a la izquierda

Resumen

En esta práctica hacemos uso del comando shl para realizar un desplazamiento hacia la izquierda e imprimimos el resultado en consola.

Objetivo

El objetivo de esta práctica es comprender el funcionamiento, aprender y conocer las operaciones de desplazamiento en Ensamblador para obtener un valor binario con shl

Introducción

El comando shl en Ensamblador es una instrucción que realiza un desplazamiento lógico hacia la izquierda de los bits de un operando. Esto significa que los bits se mueven una cierta cantidad de posiciones hacia la izquierda, y los bits más significativos se pierden mientras que los menos significativos se rellenan con ceros. El comando shl puede ser útil para realizar operaciones aritméticas como multiplicaciones o divisiones por potencias de dos.

Para comprender un poco mejor lo mencionado anteriormente, en esta práctica vamos a hacer un programa en Ensamblador que desplace los bits hacia la izquierda haciendo uso de un operando a desplazar y nuestro contador.

Metodología

Section .data

Definimos las variables a utilizar para la ejecución de este programa. En este caso solo definimos nuestras variables para realizar un salto de línea.

Section .bss

Definimos la variable resultado. AL definirla en esta sección almacenamos un byte en memoria para el almacenamiento de la variable.

Section .text

Definimos el punto de entrada al programa e iniciamos la ejecución. Empezamos moviendo el valor 2 al registro ebx. Con la instrucción shl ebx, 1 realizamos nuestro desplazamiento a la izquierda en el mismo registro. Esto en términos más simples, equivale a multiplicar por 2 por lo que ahora el registro ebx posee un valor de 4.

Con la instrucción add ebx, 48 sumamos un 48 al valor de ebx. Esto para que corresponda al valor ASCII del número 4. Acto seguido, con la instrucción mov [resultado],ebx almacenamos el valor del registro ebx en nuestra variable resultado.

Haciendo uso del número 4 llamamos a la función write del sistema para imprimir el resultado, con el 1 llamamos a la función exit y finalmente int 0x80 para invocar la interrupción en el sistema y llamar a la función de escribir. Después de esto, llamamos a nuestro salto de línea nuevamente con las funciones write y exit. Terminamos el programa con la función exit para finalizarlo y cargamos antes de salir los valores 1 y 0 en los registros eax y ebx

Resultados

Análisis

Obtuvimos como resultado lo que se esperaba, un 4 impreso en la consola del sistema. En comparación a anteriores prácticas, en esta se logró finalmente un salto de línea.

Conclusiones

La práctica se concluyó de manera exitosa y sin ningún contratiempo logrando un desplazamiento exitoso hacia la izquierda. La práctica fue relativamente fácil y el hecho de tener a la mano la tabla ASCII para poder imprimir correctamente los caracteres requeridos lo facilita aún más.

Referencias

2.14 Desplazamiento y rotación. (2018, 12 noviembre). Lenguajes de interfaz. https://ittlenguajesdeinterfaz.wordpress.com/2-14-desplazamiento-y-rotacion/ Instrucciones de Desplazamiento, Rotación y Adeudos. (s. f.). http://hernandez-gonzalez-lenguajes.blogspot.com/2013/10/instrucciones-de-desplazamiento.html

Práctica #8: Desplazamiento a la derecha

Resumen

En esta práctica hacemos uso del comando shr para realizar un desplazamiento hacia la izquierda e imprimimos el resultado en consola.

Objetivo

El objetivo de esta práctica es comprender el funcionamiento, aprender y conocer las operaciones de desplazamiento en Ensamblador para obtener un valor binario con shr

Introducción

El comando shr en Ensamblador es una instrucción que realiza un desplazamiento lógico hacia la derecha de los bits de un operando. Esto significa que los bits se mueven una cierta cantidad de posiciones hacia la derecha, y los bits menos significativos se pierden mientras que los más significativos se rellenan con ceros. El comando shr puede ser útil para realizar operaciones aritméticas como multiplicaciones o divisiones por potencias de dos.

Para comprender un poco mejor lo mencionado, en esta práctica vamos a hacer un programa en Ensamblador que desplace los bits hacia la derecha haciendo uso de un operando a desplazar y nuestro contador.

Metodología

Section .data

Definimos las variables a utilizar para la ejecución de este programa. En este caso solo definimos nuestras variables para realizar un salto de línea.

Section .bss

Definimos la variable resultado. AL definirla en esta sección almacenamos un byte en memoria para el almacenamiento de la variable.

Section .text

Definimos el punto de entrada al programa e iniciamos la ejecución. Empezamos moviendo el valor 2 al registro ebx. Con la instrucción shr ebx, 1 realizamos nuestro desplazamiento a la derecha en el mismo registro. Esto en términos más simples, equivale a dividir por 2 por lo que ahora el registro ebx posee un valor de 1.

Con la instrucción add ebx, 48 sumamos un 48 al valor de ebx. Esto para que corresponda al valor ASCII del número 1. Acto seguido, con la instrucción mov [resultado],ebx almacenamos el valor del registro ebx en nuestra variable resultado.

Haciendo uso del número 4 llamamos a la función write del sistema para imprimir el resultado, con el 1 llamamos a la función exit y finalmente int 0x80 para invocar la interrupción en el sistema y llamar a la función de escribir. Después de esto, llamamos a nuestro salto de línea nuevamente con las funciones write y exit. Terminamos el programa con la función exit para finalizarlo y cargamos antes de salir los valores 1 y 0 en los registros eax y ebx

Resultados

Análisis

Obtuvimos como resultado lo que se esperaba, un 1 impreso en la consola del sistema. Al ser una práctica similar a la anterior no hubo muchas complicaciones.

Conclusiones

La práctica se concluyó de manera exitosa y sin ningún contratiempo logrando un desplazamiento exitoso hacia la derecha. La práctica fue bastante sencilla de realizas ya que es el mismo código que en la anterior con la única diferencia en la instrucción para desplazar.

Referencias

2.14 Desplazamiento y rotación. (2018, 12 noviembre). Lenguajes de interfaz. https://ittlenguajesdeinterfaz.wordpress.com/2-14-desplazamiento-y-rotacion/ Instrucciones de Desplazamiento, Rotación y Adeudos. (s. f.). http://hernandez-gonzalez-lenguajes.blogspot.com/2013/10/instrucciones-de-desplazamiento.html

Práctica #9: Rotación a la izquierda

Resumen

En esta práctica hacemos uso del comando rol para realizar una rotación hacia la izquierda e imprimiendo el resultado de dicha rotación en consola.

Objetivo

El objetivo de esta práctica es aprender y conocer el funcionamiento de uno de los comandos que conforman las instrucciones de corrimiento de Ensamblador.

Introducción

El comando rol en Ensamblador es una instrucción que realiza un desplazamiento rotatorio hacia la izquierda de los bits de un operando. Esto significa que los bits se mueven una cierta cantidad de posiciones hacia la izquierda, y el bit más significativo se desplaza al flag C y al bit menos significativo del operando. El comando rol puede ser útil para realizar operaciones aritméticas como multiplicaciones o divisiones por potencias de dos con o sin signo. Para comprender un poco mejor, a continuación se realizará una práctica haciendo uso de este comando.

Metodología

Section .data

Definimos las variables a utilizar para la ejecución de este programa. En este caso solo definimos nuestras variables para realizar un salto de línea.

Section .bss

Definimos la variable resultado. AL definirla en esta sección almacenamos un byte en memoria para el almacenamiento de la variable.

Section .text

Definimos el punto de entrada al programa e iniciamos la ejecución. Con la instrucción mov bl, 128 movemos el numero 128 al registro BL. Acto seguido, con la instrucción rol bl, 1 realizamos una rotación circular a la izquierda en dicho registro. Después, sumamos 48 al registro bl después de realizar la rotación para poder convertirlo al valor correcto de acuerdo a la tabla ASCII.

Acto seguido, con la instrucción mov [resultado], bl almacenamos el valor del registro bl en nuestra variable resultado.

Haciendo uso del número 4 llamamos a la función write del sistema para imprimir el resultado, con el 1 llamamos a la función exit y finalmente int 0x80 para invocar la interrupción en el sistema y llamar a la función de escribir. Después de esto, llamamos a nuestro salto de línea nuevamente con las funciones write y exit. Terminamos el programa con la función exit para finalizarlo y cargamos antes de salir los valores 1 y 0 en los registros eax y ebx.

Resultados

Análisis

De acuerdo al valor que introducimos, el que nos imprima un 1 al correr el programa es bastante acertado y lo esperado. Esto sucede ya que el 128 almacenado en el registro bl equivale a 10000000 en binario. Al aplicar una rotación hacia la izquierda el bit más significativo se mueve al extremo derecho por lo que al final tenemos como valor final un 1 (00000001 en binario).

Conclusiones

Esta práctica fue algo sencilla, no obstante, al estar manejando los números binarios esto aumenta un poco la dificultad al querer obtener como resultado algún número o carácter en específico.

Referencias

2.14 Desplazamiento y rotación. (2018, 12 noviembre). Lenguajes de interfaz. https://ittlenguajesdeinterfaz.wordpress.com/2-14-desplazamiento-y-rotacion/ Instrucciones de Desplazamiento, Rotación y Adeudos. (s. f.). http://hernandez-gonzalez-lenguajes.blogspot.com/2013/10/instrucciones-de-desplazamiento.html

Práctica #10: Rotación a la derecha

Resumen

En esta práctica hacemos uso del comando ror para realizar una rotación hacia la derecha e imprimiendo el resultado de dicha rotación en consola.

Objetivo

El objetivo de esta práctica es aprender y conocer el funcionamiento de uno de los comandos que conforman las instrucciones de corrimiento de Ensamblador.

Introducción

El comando ror en Ensamblador es una instrucción que realiza un desplazamiento rotatorio hacia la derecha de los bits de un operando. Esto significa que los bits se mueven una cierta cantidad de posiciones hacia la derecha, y el bit menos significativo se desplaza al flag C y al bit más significativo del operando. El comando ror puede ser útil para realizar operaciones aritméticas como multiplicaciones o divisiones por potencias de dos con o sin signo. Para comprender un poco mejor, a continuación se realizará una práctica haciendo uso de este comando.

Metodología

Section .data

Definimos las variables a utilizar para la ejecución de este programa. En este caso solo definimos nuestras variables para realizar un salto de línea.

Section .bss

Definimos la variable resultado. AL definirla en esta sección almacenamos un byte en memoria para el almacenamiento de la variable.

Section .text

Definimos el punto de entrada al programa e iniciamos la ejecución. Con la instrucción mov bl, 128 movemos el numero 128 al registro BL. Acto seguido, con la instrucción ror bl, 1 realizamos una rotación circular a la derecha en dicho registro. Después, sumamos 48 al registro bl después de realizar la rotación para poder convertirlo al valor correcto de acuerdo a la tabla ASCII.

Acto seguido, con la instrucción mov [resultado], bl almacenamos el valor del registro bl en nuestra variable resultado.

Haciendo uso del número 4 llamamos a la función write del sistema para imprimir el resultado, con el 1 llamamos a la función exit y finalmente int 0x80 para invocar la interrupción en el sistema y llamar a la función de escribir. Después de esto, llamamos a nuestro salto de línea nuevamente con las funciones write y exit. Terminamos el programa con la función exit para finalizarlo y cargamos antes de salir los valores 1 y 0 en los registros eax y ebx.

Resultados

Análisis

De acuerdo al valor que introducimos, el que nos imprima una p al correr el programa es bastante acertado. Esto sucede ya que el 128 almacenado en el registro bl equivale a 10000000 en binario. Al aplicar una rotación hacia la derecha el bit más significativo se mueve al extremo menos significativo mientras que los demás bits se mueven hacia la derecha por lo que al final tenemos como valor final un 64 (01000000 en binario). Después de realizar la suma del 48 nos queda un valor de 112 (01110000 en binario). Siendo el 112 correspondiente al carácter 'p' en la tabla ASCII.

Conclusiones

AL igual que con la practica anterior, esta práctica fue relativamente sencilla aunque en lo personal algo confusa al estar tomando en cuenta la equivalencia de los números binarios para la realización de estas operaciones de desplazamiento.

Referencias

2.14 Desplazamiento y rotación. (2018, 12 noviembre). Lenguajes de interfaz. https://ittlenguajesdeinterfaz.wordpress.com/2-14-desplazamiento-y-rotacion/ Instrucciones de Desplazamiento, Rotación y Adeudos. (s. f.). http://hernandez-gonzalez-lenguajes.blogspot.com/2013/10/instrucciones-de-desplazamiento.html

Práctica #11: Entrada de datos en consola

Resumen

En esta práctica desarrollamos un programa en Ensamblador que permite al usuario ingresar un dato numérico por medio del teclado de la computadora, al final nuestro programa mostrará en consola el número ingresado.

Objetivo

Leer datos por medio del teclado de la computadora y hacer uso de dichos datos.

Introducción

En esta práctica hacemos uso del teclado para leer y guardar datos en variables, contrario a prácticas anteriores donde estos eran precargados con anticipación en el código y limitaban la interacción del usuario con el programa. Para ello, se ejecutara el programa en la consola y se utilizaran llamadas al sistema para realizar operaciones de E/S.

Metodología

Section .data

Definimos las variables a utilizar para la ejecución de este programa. A continuación se explica a continuación que y que fue definido en esta sección:

  • Msg1: Es una cadena de caracteres que fue definida para contener el mensaje "Introducir un numero" y un carácter de salto de línea (representado por 10 en código ASCII).

  • Msg1Len: Es una constante que definimos haciendo uso del operador equ, fue hecha para almacenar la longitud de la cadena Msg1.

  • Msg2: Es una cadena de caracteres que fue definida para contener el mensaje "El número que ingresaste es: ".

  • Msg2Len: Es una constante que definimos haciendo uso del operador equ, fue hecha para almacenar la longitud de la cadena Msg2.

  • Msg3: Es un carácter para definir un salto de línea.

  • numero: Es una variable que se utiliza para almacenar el número ingresado por el usuario.

Section .text

Definimos el punto de entrada al programa e iniciamos la ejecución. Con la instrucción mov eax, 4 cargamos el valor 4 en el registro eax para indicar que vamos a realizar una llamada al sistema para imprimir un mensaje en la salida estándar.

Acto seguido, con la instrucción mov ebx, 1 cargamos el valor 1 en el registro ebx para indicar que se imprimirá en la salida estándar. Después, con la instrucción mov ecx, Msg1 vamos a cargar la dirección de la memoria de la cadena Msg1 en el registro ecx para eventualmente va a pasarse a la llamada al sistema.

Con la instrucción edx, Msg1Len cargamos el valor de la constante mencionada en dicha instrucción en el registro edx, con esto estamos indicando la longitud del mensaje a imprimir. Después con la instrucción 0x80 realizamos la llamada al sistema para que imprima el mensaje en pantalla. Después tenemos instrucciones similares a continuación que hacen el mismo procedimiento explicado aquí solamente que con las variables Msg2, Msg3 y el número que se ingrese por medio del teclado.

Terminamos el programa con la función exit para finalizarlo y cargamos antes de salir los valores 1 y 0 en los registros eax y ebx.

Resultados

Análisis

Con este código, cambiamos finalmente la metodología que hemos estado llevando hasta el momento en relación con las prácticas anteriores en Ensamblador y abre la posibilidad a crear programas similares a los anteriores o más complejos con datos ingresados por los mismos usuarios.

Conclusiones

La práctica se completó de manera exitosa, se ha aprendido como leer datos por medio de una entrada por parte del usuario en el teclado. Como se mencionó anteriormente, este código abre las posibilidades a empezar con programas más complejos y a recrear los anteriores pero esta vez añadiendo entradas por medio del teclado.

Referencias

  • N/A.

Práctica #12: Saltos incondicionales

Resumen

En esta práctica realizaremos un programa en Ensamblador en el que haremos uso por primera vez de los saltos incondicionales.

Objetivo

El objetivo de esta práctica, es conocer a fondo la instrucción jmp y como utilizarla para nuestros programas en Ensamblador para poder ceder el control a otra sección de nuestro código.

Introducción

Los saltos incondicionales se realizan siempre que se ejecuta la instrucción y no depende de ninguna condición como su nombre lo indica. Estos hacen que el programa salte a una nueva dirección y son utilizados para creas bucles, subrutinas, estructuras de selección múltiple, etc. A continuación, se presenta como se hizo uso de esta instrucción:

Metodología

Empezamos definiendo nuestra sección de datos, donde vamos a definir dos cadenas de texto que contienen "Etiqueta 1" y "Etiqueta 2" seguidas de los caracteres 10 y 13 para realizar un salto de línea y finalizar la línea. Después de ello, definimos dos constantes lonmsg1 y lonmsg2 usando equ, con ellas determinamos la longitud de nuestras cadenas en líneas más adelante. Adicionalmente definimos una sección bss para reservar memoria para datos no inicializados aunque en esta ocasión no estamos haciendo uso de ella.

Definimos el punto de entrada al programa con _start, empezamos ejecutando la primera instrucción para hacer un salto incondicional a la sección etiqueta2, esta función imprime la cadena "etiqueta 2" al igual que la sección etiqueta1 que en su lugar solamente imprime "etiqueta 1".

Haciendo uso del número 4 llamamos a la función write del sistema para imprimir el resultado, con el 1 llamamos a la función exit y finalmente int 0x80 para invocar la interrupción en el sistema y llamar a la función de escribir. Después de esto, llamamos a nuestro salto de línea nuevamente con las funciones write y exit. Terminamos el programa con la función exit para finalizarlo y cargamos antes de salir los valores 1 y 0 en los registros eax y ebx.

Resultados

Análisis

La practica pudo completarse de manera exitosa y obteniendo los resultados esperados demostrando la funcionalidad que podemos tener en nuestro código al implementar los saltos incondicionales así como también aprender mejor como es que se funcionan e imaginar como podríamos aplicarlos en situaciones más complejas.

Conclusiones

Se ha aprendido como hacer uso de la instrucción "jmp" para poder hacer saltos a etiquetas en específico de nuestro código y continuar con la ejecución del programa. Esta fue una buena práctica introductoria a los saltos de esta naturaleza debido a su sencillez.

Referencias

NA.

Práctica #13: Saltos condicionales

Resumen

En esta práctica realizaremos un programa en Ensamblador en el que haremos uso por primera vez de los saltos condicionales.

Objetivo

El objetivo de esta práctica, es conocer a fondo la instrucción je y como utilizarla para nuestros programas en Ensamblador para poder ceder el control a otra sección de nuestro código.

Introducción

Los saltos condicionales son instrucciones que hacen que el programa salte a una dirección nueva solo si se cumple determinada condición. Se usan para crear estructuras de selección simple o múltiple, como IF o SWITCH. A continuación, se presenta como se hizo uso de esta instrucción:

Metodología

Empezamos definiendo en nuestra sección .data una cadena de caracteres bajo el nombre "msg" que contendrá un mensaje de error que se desplegara en caso de que nuestro segundo número sea cero. Junto a esta cadena, definimos lonmsg que vendría siendo la longitud correspondiente de nuestro mensaje de error. Acto seguido, en la sección .bss reservamos un byte de memoria para almacenar el resultado de la división.

Después de ello, empezamos a definir el punto de entrada a nuestro código, en primer lugar tenemos un conjunto de instrucciones que se encargaran de mover los valores a los registros necesarios para realizar la operación aritmética. Movemos el valor 2 al registro ebx siendo en este caso el divisor de la operación. Luego, se realiza una comparación para determinar si el divisor es cero. Si es así, salta a la etiqueta "escero" que muestra el mensaje de error. En caso contrario se ejecuta la instrucción "div ebx", que divide el valor almacenado en el registro eax por el valor almacenado en ebx. Después de la división, se agrega el valor 48 al registro ebx para convertir el resultado de la división en un carácter ASCII correspondiente al dígito numérico obtenido. El resultado se almacena en la memoria reservada en la sección .bss.

Haciendo uso del número 4 llamamos a la función write del sistema para imprimir el resultado, con el 1 llamamos a la función exit y finalmente int 0x80 para invocar la interrupción en el sistema y llamar a la función de escribir. Después de esto, llamamos a nuestro salto de línea nuevamente con las funciones write y exit. Terminamos el programa con la función exit para finalizarlo y cargamos antes de salir los valores 1 y 0 en los registros eax y ebx.

Resultados

Análisis

La práctica pudo completarse de manera exitosa y obteniendo los resultados esperados demostrando la funcionalidad que podemos tener en nuestro código al implementar los saltos condicionales para evitar errores, siendo en este caso que si llega un cero desvía el flujo del programa para imprimir el mensaje de error y evitar una división entre cero.

Conclusiones

Durante el desarrollo de esta práctica pudimos ver y aplicar el uso de varias instrucciones para desarrollar un programa sencillo aplicando los saltos condicionales que como se mencionó anteriormente, son capaces de desviar el flujo del programa siempre y cuando se cumplan determinadas condiciones. Podemos concluir que los saltos pueden ser bastante útiles a la hora de programar en ensamblador.

Referencias

NA.

Práctica #14: División con entrada de teclado.

Resumen

En esta práctica hacemos una fusión de la práctica #11 (entrada de datos por teclado) y la práctica #6 (división) para lograr hacer una división usando números introducidos por el usuario.

Objetivo

El objetivo de esta práctica es comenzar a realizar programas más complejos en Ensamblador, haciendo uso del conocimiento adquirido en prácticas anteriores.

Introducción

Para esta práctica haremos nuevamente uso de la entrada por medio del teclado, esto con el objetivo de obtener números por medio del usuario y hacer la división entre los mismos. Nos apoyaremos de las prácticas #6 y #11 para la realización de esta práctica.

Metodología

El programa comienza definiendo algunas variables en la sección .data y .bss. En .data, se definen dos mensajes de texto. Msg1 es un mensaje que se mostrará al usuario para solicitar un número. msg es un mensaje que se mostrará en caso de que el usuario ingrese cero. En .bss, se definen dos variables: Numero y resultado. Numero es donde se almacenará el número ingresado por el usuario, y "resultado" es donde se almacenará el resultado de la división.

El punto de entrada es _start. El primer bloque de código muestra el mensaje Msg1 para solicitar un número al usuario. Esto se hace llamando a la función del sistema para escribir en la salida estándar (mov eax, 4 y int 0x80). El siguiente bloque de código lee un solo byte (un número) desde la entrada estándar (mov eax, 3 y int 0x80) y lo almacena en Numero.

Luego, el programa convierte el número ingresado en un valor entero mediante sub eax, 48 (debido a que la entrada es un valor ASCII). A continuación, el programa verifica si el número ingresado es cero (cmp ebx, 0). Si es cero, salta a la etiqueta escero y muestra el mensaje de error msg en la salida estándar.

Si el número ingresado es distinto de cero, el programa divide el número entre dos (div ebx). El resultado de la división se almacena en eax, que luego se convierte de nuevo a un valor ASCII mediante add eax, 48. Finalmente, el programa muestra el resultado de la división en la salida estándar mediante mov eax, 4 y int 0x80.

Haciendo uso del número 4 llamamos a la función write del sistema para imprimir el resultado, con el 1 llamamos a la función exit y finalmente int 0x80 para invocar la interrupción en el sistema y llamar a la función de escribir. Después de esto, llamamos a nuestro salto de línea nuevamente con las funciones write y exit. Terminamos el programa con la función exit para finalizarlo y cargamos antes de salir los valores 1 y 0 en los registros eax y ebx.

Resultados

Análisis

Obtuvimos los resultados esperados en esta sencilla pero algo compleja practica que nos permitió aplicar lo que hemos aprendido de prácticas anteriores. Tuvo su grado de complejidad (sobre todo con lo de la entrada en ASCII) pero al final todo pudo concluir de manera exitosa.

Conclusiones

La práctica se concluyó de manera exitosa, logrando aplicar conocimientos de prácticas anteriores y subiendo un poco la complejidad de la practicas que realizamos. En lo personal creo que es un buen inicio para dar pie a empezar a hacer programas mucho más complejos en los que podamos aplicar lo que se ha aprendido hasta el momento.

Referencias

NA.