Tema II: Programación básica - Axelrpg/Lenguajes-de-interfaz GitHub Wiki

2.1 - Ensamblador (y ligador) a utilizar

El ensamblador es un lenguaje de programación de bajo nivel que se utiliza para interactuar con el hardware de una computadora. Cada procesador tiene su propio conjunto de instrucciones, por lo que se necesita un ensamblador específico. Algunos ejemplos son NASM, FASM y GAS. Aunque todos los ensambladores hacen lo mismo, pueden tener diferentes características.

Clasificación de ensambladores

Ensambladores Cruzados (Cross-Assembler)

Los ensambladores cruzados son herramientas que se usan en una computadora para generar programas que se ejecutarán en otras computadoras con procesadores diferentes. Esto permite desarrollar programas en una máquina más potente y con mayor soporte de hardware y programación, para luego ejecutarlos en sistemas especializados en tareas específicas.

Ensambladores Residentes

Los ensambladores residentes son aquellos que permanecen en la memoria principal de la computadora y cargan el programa objeto para su ejecución. Esto permite comprobar inmediatamente el programa sin necesidad de transportarlo o usar programas simuladores. Sin embargo, pueden presentar problemas de espacio de memoria ya que ocupan espacio que no puede ser utilizado por el programador. Estos ensambladores son adecuados para pequeños sistemas de control y sencillos automatismos con microprocesadores. La ventaja es la ejecución inmediata del programa, pero la desventaja es que ocupan memoria principal junto al programa fuente y objeto.

Macroensambladores

Los ensambladores que permiten el uso de macros se denominan "ensambladores con macros". Son programas robustos que pueden definir y manipular macroinstrucciones, lo que les otorga una mayor complejidad. A diferencia de los ensambladores residentes, estos no permanecen en memoria después de generar el programa objeto. La complejidad de estos programas puede variar según las posibilidades de definición y manipulación de las macroinstrucciones.

Microensambladores

Los procesadores en las computadoras tienen un conjunto de instrucciones fijo que es interpretado de la misma manera. El programa que controla cómo se ejecutan estas instrucciones se llama microprograma y se usa un microensamblador para crearlo. Algunos procesadores pueden modificar su microprograma, y para hacerlo se utiliza un microensamblador.

Ensambladores de una fase

Los ensambladores de un solo pase traducen una línea del programa fuente directamente a lenguaje máquina o la ejecutan como una pseudoinstrucción. Mientras lo hacen, también construyen una tabla de símbolos que incluye definiciones de variables y etiquetas. Estos ensambladores son simples y económicos, pero requieren que los símbolos se definan antes de que se usen para que las referencias a ellos en las instrucciones se traduzcan correctamente.

Ensambladores de dos fases

Los ensambladores de dos fases se llaman así porque traducen el programa en dos etapas. En la primera etapa, leen el programa y construyen una tabla de símbolos. En la segunda etapa, vuelven a leer el programa y traducen todo, ya que conocen todos los símbolos y sus posiciones. Estos ensambladores son los más utilizados hoy en día.

2.2 - Ciclos numéricos

La arquitectura de los procesadores x86 usa segmentos de memoria para manejar la información, cada uno de 64kb. Esto se debe a que el tamaño máximo de un número que puede manejar el procesador es de 16 bits, lo que limita el acceso a solo 65536 localidades de memoria por registro. Para acceder a más memoria, la PC divide la memoria en segmentos de 65536 localidades cada uno y utiliza un registro para localizar cada segmento. Cada dirección de una casilla específica se forma con dos registros, lo que permite acceder a una gran cantidad de memoria. El ensamblador accede a los datos y las instrucciones a través de los registros DS, ES, SS y CS, tomando en cuenta la localización del segmento y la dirección del dato específico.

2.3 - Captura básica de cadenas

En el lenguaje ensamblador el tipo de dato cadena (string) no está definido, pero para fines de programación, una cadena es definida como un conjunto de localidades de memoria consecutivas que se reservan bajo el nombre de una variable.

Instrucciones para el manejo de strings

MOVSB

Mueve un byte desde una localidad de memoria hasta otra.

MOVSW

Mueve una palabra desde una localidad de memoria hasta otra.

LODS (cargar un byte o palabra)

Este programa en MASM carga el registro acumulador (AX o AL) con el valor de la localidad de memoria determinada por DS:SI y se incrementa tras la transferencia. En el ejemplo, capturamos una cadena en un vector y la imprimimos varias veces según la preferencia del usuario. Este programa sirve para aprender cómo usar vectores en MASM. Los vectores se pueden declarar con cualquier tipo de dato y longitud específica, utilizando la palabra reservada "dup".

2.4 - Comparación y prueba

La instrucción CMP se utiliza para comparar dos campos de datos, uno de los cuales está contenido en un registro. Por otro lado, la instrucción CMPS compara el contenido de una localidad de memoria, incrementando o disminuyendo los registros SI y DI según la bandera de dirección. CMPS también establece las banderas AF, CF, OF, PF, SF y ZF. Con un prefijo REP y una longitud en CX, CMPS puede comparar cadenas de cualquier longitud. Sin embargo, CMPS realiza una comparación alfanumérica según los valores ASCII. Hay derivaciones de CMPS, como CMPSB para comparar bytes, CMPSD para palabras dobles y CMPSW para palabras.

2.5 - Saltos

Los programas a menudo repiten una serie de pasos hasta cumplir un requisito específico y utilizan la instrucción JMP para transferir el control de forma incondicional. Sin embargo, un programa con muchos saltos puede ser lento. Por otro lado, la instrucción LOOP usa el registro CX para disminuir automáticamente 1 en cada iteración. Si el valor en CX es cero, el control pasa a la siguiente instrucción; de lo contrario, el control pasa a la dirección indicada. La distancia del salto debe ser corta, de -128 a +127 bytes. Si la operación excede este límite, el ensamblador envía un mensaje de error.

2.6 - Ciclos condicionales

Los ciclos condicionales son una herramienta fundamental en la programación, ya que permiten a los programas tomar decisiones basadas en condiciones específicas. En términos generales, los ciclos condicionales son una estructura de control de flujo que indica al programa qué hacer si se cumple una condición determinada, y qué hacer si no se cumple. La instrucción "if" es una de las formas más comunes de ciclos condicionales, ya que permite evaluar una condición y ejecutar un bloque de código específico si la condición es verdadera. En algunos lenguajes de programación, también se utiliza la instrucción "else" para ejecutar un bloque de código diferente si la condición es falsa. En ensamblador, existen diferentes ciclos condicionales, cada uno con su propia sintaxis y forma de uso.

  • Loop: La instrucción loop decrementa CX en 1, y transfiere el flujo del programa a la etiqueta dada como operando si CX es diferente a 1.
  • Loope: Esta instrucción decrementa CX en 1. Si CX es diferente a cero y ZF es igual a 1, entonces el flujo del programa se transfiere a la etiqueta indicada como operando.
  • Loopne: Esta instrucción decrementa en uno a CX y transfiere el flujo del programa solo si ZF es diferente a 0.

2.7 - Incremento y decremento

Las instrucciones de INC y DEC son fundamentales para realizar operaciones con registros en programación. INC se utiliza para aumentar el valor de un registro o posición de memoria en una unidad, mientras que DEC se utiliza para disminuirlo en una unidad. Estas instrucciones son esenciales para la realización de operaciones matemáticas y manipulación de datos en el lenguaje de programación.

2.8 - Captura de cadenas con formato

La captura de cadenas con formato es una técnica muy útil en programación para leer datos de entrada en un formato particular. Esta técnica permite manipular, comparar o buscar rápidamente entre bloques de datos. En el lenguaje ensamblador, se utilizan ciertas instrucciones para capturar cadenas con formato y realizar operaciones con ellas.

  • MOVC: Esta instrucción permite transferir un carácter de una cadena.
  • MOVW: Esta instrucción permite transferir una palabra de una cadena.
  • CMPC: Este comando es utilizado para comparar un carácter de una cadena.
  • CMPW: Esta instrucción es utilizada para comparar una palabra de una cadena.
  • SCAC: Esta instrucción permite buscar un carácter de una cadena.
  • SCAW: Esta instrucción se utiliza para buscar una palabra de una cadena.
  • LODC: Esta instrucción permite cargar un carácter de una cadena.
  • LODW: Esta instrucción es utilizada para cargar una palabra de una cadena.
  • STOC: Esta instrucción permite guardar un carácter de una cadena.
  • STOW: Esta instrucción es utilizada para guardar una palabra de una cadena.

2.9 - Instrucciones aritméticas

  • ADC: Adición con carreo. Lleva a cabo la suma de dos operandos y suma uno al resultado en caso de que la bandera CF esté activada, esto es, en caso de que exista acarreo. El resultado se guarda en el operando destino.
  • ADD: Adición de los operandos. Suma los dos operandos y guarda el resultado en el operando destino.
  • DIV: División sin signo. El divisor puede ser un byte o palabra y es el operando que se le da a la instrucción. Si el divisor es de 8 bits se toma como dividendo el registro de 16 bits AX y si el divisor es de 16 bits se tomara como dividendo el registro par DX:AX, tomando como palabra alta DX y como baja AX. Si el divisor fue un byte el cociente se almacena en el registro AL y el residuo en AH, sí fue una palabra el cociente se guarda en AX y el residuo en DX.
  • IDIV: División con signo. Consiste básicamente en lo mismo que la instrucción DIV, solo que esta última realiza la operación con signo.
  • MUL: Multiplicación sin signo. El ensamblador asume que el multiplicando sera del mismo tamaño que el del multiplicador, por lo tanto multiplica el valor almacenado en el registro que se le da como operando por el que se encuentre contenido en AH si el multiplicador es de 8 bits o por AX si el multiplicador es de 16 bits. Cuando se realiza una multiplicación con valores de 8 bits el resultado se almacena en el registro AX y cuando la multiplicación es con valores de 16 bits el resultado se almacena en el registro par DX:AX.
  • IMUL: Multiplicación de dos enteros con signo. Este comando hace lo mismo que el anterior, solo que si toma en cuenta los signos de las cantidades que se multiplican. Los resultados se guardan en los mismos registros que en la instrucción MUL.
  • SBB: Substracción con acarreo. Esta instrucción resta los operandos y resta uno al resultado si CF está activada. El operando fuente siempre se resta del destino. Este tipo de substracción se utiliza cuando se trabaja con cantidades de 32 bits.
  • SUB: Substracción. Resta el operando fuente del destino.

2.10 - Manipulación de la pila

La manipulación de la pila es una técnica fundamental en la programación en ensamblador que permite a los programadores almacenar y recuperar valores de forma eficiente. En ensamblador, la pila es una estructura de datos que se utiliza para almacenar temporalmente valores y direcciones de retorno durante la ejecución del programa.

Las instrucciones de la pila en ensamblador incluyen PUSH, que coloca un valor en la parte superior de la pila, y POP, que retira el valor de la parte superior de la pila. También hay instrucciones que permiten mover datos dentro de la pila, como MOV y XCHG.

Además, la pila se utiliza comúnmente en la implementación de funciones y subrutinas, donde los valores de los registros y las direcciones de retorno se almacenan en la pila antes de que la función o subrutina se ejecute. Una vez que la función o subrutina ha terminado de ejecutarse, los valores se recuperan de la pila y se restauran los registros y la dirección de retorno.

La manipulación de la pila es esencial para garantizar que los programas en ensamblador funcionen correctamente y de manera eficiente. Sin la capacidad de almacenar y recuperar valores de la pila, muchos programas serían mucho más difíciles de escribir y menos eficientes.

2.11 Obtención de cadena con representación decimal

En este modo, los datos son proporcionados directamente como parte de la instrucción. Ejemplo:

Mov AX,34h ;
Copia en AX el número 34h hexadecimal Mov CX,10 ;
Copia en CX el número 10 en decimal
.COMMENT
Programa: PushPop.ASM
Descripción: Este programa demuestra el uso de las instrucciones para el manejo de la pila, implementando la instrucción XCHG con Push y Pop
MODEL tiny
.CODE

Inicio: ;Punto de entrada al programa
Mov AX,5 ;AX=5
Mov BX,10 ;BX=10
Push AX ;Pila=5
Mov AX,BX ;AX=10
Pop BX ;BX=5
Mov AX,4C00h ;Terminar programa y salir al DOS
Int 21h ;
END Inicio
END

2.12 Instrucciones lógicas

AND

Realiza la conjunción de los operandos bit por bit. Sintaxis y ejemplo:

AND destino, fuente

AND ax, bx

NOT

Lleva a cabo la negación bit por bit del operando destino. Sintaxis y ejemplo:

NOT destino

NOT ax

OR

La instrucción OR lleva a cabo, bit por bit, la disyunción inclusiva lógica de los dos operandos. Sintaxis y ejemplo:

OR destino, fuente

OR ax,bx

XOR

Su función es efectuar bit por bit la disyunción exclusiva lógica de los dos operandos. Sintaxis y ejemplo:

XOR destino, fuente

XOR ax, bx

NEG

Genera el complemento a 2 del operando destino y lo almacena en este mismo operando. Sintaxis y ejemplo:

NEG destino

NEG ax

TEST

Realiza una conjunción, bit por bit, de los operandos, pero a diferencia de AND esta instrucción no coloca el resultado en el operando destino, solo tiene efecto sobre el estado de las banderas.

TEST destino, fuente

TEST ax, bx

2.13 Desplazamiento y rotación

Las instrucciones de corrimiento, que son parte de la capacidad lógica de la computadora, pueden realizar las siguientes acciones:

  1. Hacer referencia a un registro o dirección de memoria.
  2. Recorre bits a la izquierda o a la derecha.
  3. Recorre hasta 8 bits en un byte, 16 bits en una palabra y 32 bits en una palabra doble.
  4. Corrimiento lógico (sin signo) o aritmético (con signo).

Desplazamiento o corrimiento de bits hacia la derecha

Los corrimientos hacia la derecha (SHR y SAR) mueven los bits hacia la derecha en el registro designado. El bit recorrido fuera del registro mete la bandera de acarreo. Las instrucciones de corrimiento a la derecha estipulan datos lógicos (sin signo) o aritméticos (con signo):

SAR se difiere de SHR en un punto importante SAR utiliza el bit de signo para llenar el bit vacante de más a la izquierda. De esta manera, los valores positivos y negativos retienen sus signos. Las siguientes instrucciones relacionadas ilustran SAR y datos con signo en los que el signo es un bit 1:

En especial, los corrimientos a la derecha son útiles para (dividir entre 2) obtener mitades de valores y son mucho más rápidas que utilizar una operación de división. Al terminar una operación de corrimiento, puede utilizar la instrucción JC (Salta si hay acarreo) para examinar el bit desplazado a la bandera de acarreo.

Desplazamiento o corrimiento de bits a la izquierda

Los corrimientos hacia la izquierda (SHL y SAL) mueven los bits a la izquierda, en el registro designado. SHL y SAL son idénticos en su operación. El bit desplazado fuera del registro ingresa a la bandera de acarreo. Las instrucciones de corrimiento hacia la izquierda estipulan datos lógicos (sin signo) y aritméticos (con signo).

  • SHL: Desplazamiento lógico a la izquierda
  • SAL: Desplazamiento aritmético a la izquierda

Los corrimientos a la izquierda llenan con cero el bit de más a la derecha. Como resultado de esto, SHL y SAL don idénticos. Los corrimientos a la izquierda en especial son útiles para duplicar valores y son mucho más rápidos que usar una operación de multiplicación. Al terminar una operación de corrimiento, puede utilizar la instrucción JC (Salta si hay acarreo) para examinar el bit que ingreso a la bandera de acarreo.

Rotación de bits (desplazamiento circular)

Las instrucciones de rotación, que son parte de la capacidad lógica de la computadora, pueden realizar las siguientes acciones:

  1. Hacer referencia a un byte o a una palabra.
  2. Hacer referencia a un registro o a memoria.
  3. Realizar rotación a la derecha o a la izquierda. El bit que es desplazado fuera llena el espacio vacante en la memoria o registro y también se copia en la bandera de acarreo.
  4. Realizar rotación hasta 8 bits en un byte, 16 bits en una palabra y 32 bits en una palabra doble.
  5. Realizar rotación lógica (sin signo) o aritmética (con signo).

Rotación a la derecha

Las rotaciones a la derecha (ROR y RCR) desplazan a la derecha los bits en el registro designado. Las instrucciones de rotación a la derecha estipulan datos lógicos (sin signo) o aritméticos (con signo).

RCR provoca que la bandera de acarreo participe en la rotación. Cada bit que se desplaza fuera de la derecha se mueve al CF y el bit del CF se mueve a la posición vacante de la izquierda.

Rotación a la izquierda de bits

Las rotaciones a la izquierda (ROL y RCL) desplazan a la izquierda los bits del registro designado. Las instrucciones de rotación a la izquierda estipulan datos lógicos (sin signo) y aritméticos (con signo):

De manera similar a RCR, RCL también provoca que la bandera de acarreo participe en la rotación. Cada bit que se desplaza fuera por la izquierda se mueve al CF, y el bit del CF se mueve a la posición vacante de la derecha. Puede usar la instrucción JC (salta si hay acarreo) para comprobar el bit rotado hacia la CF en el extremo de una operación de rotación.

2.14 Obtención de una cadena con la representación hexadecimal

La conversión entre numeración binaria y hexadecimal es sencilla. Lo primero que se hace para una conversión de un número binario a hexadecimal es dividirlo en grupos de 4 bits, empezando de derecha a izquierda. En caso de que el último grupo (el que quede más a la izquierda) sea menor de 4 bits se rellenan los faltantes con ceros. Tomando como ejemplo el número binario 101011 lo dividimos en grupos de 4 bits y nos queda:

10; 1011 

Rellenando con ceros el último grupo (el de la izquierda):

0010; 1011 

después tomamos cada grupo como un número independiente y consideramos su valor en decimal:

0010 = 2; 1011 = 11 

Pero como no podemos representar este número hexadecimal como 211 porqué sería un error, tenemos que sustituir todos los valores mayores a 9 por su respectiva representación en hexadecimal, con lo que obtenemos:

2BH (Donde la H representa la base hexadecimal) 

Para convertir un número de hexadecimal a binario solo es necesario invertir estos pasos: se toma el primer dígito hexadecimal y se convierte a binario, y luego el segundo, y así sucesivamente hasta completar el número.

2.15 Captura y almacenamiento de datos numéricos

Esta representación está basada en la notación científica, esto es, representar un número en dos partes: su mantisa y su exponente. Poniendo como ejemplo el número 1234000, podemos representarlo como 1.123*10^6, en esta última notación el exponente nos indica el número de espacios que hay que mover el espacio hacia la derecha para obtener el resultado original. En caso de que el exponente fuera negativo nos estaría indicando el número de espacios que hay que recorrer el punto decimal hacia la izquierda para obtener el original.

Proceso de creación de un programa

Para la creación de un programa es necesario seguir cinco pasos: diseño del algoritmo, codificación del mismo, su traducción a lenguaje máquina, la prueba del programa y la depuración.

En la etapa de diseño se plantea el problema a resolver y se propone la mejor solución, creando diagramas esquemáticos utilizados para el mejor planteamiento de la solución.

La codificación del programa consiste en escribir el programa en algún lenguaje de programación; en este caso específico en ensamblador, tomando como base la solución propuesta en el paso anterior.

La traducción al lenguaje máquina es la creación del programa objeto, esto es, el programa escrito como una secuencia de ceros y unos que pueda ser interpretado por el procesador.

La prueba del programa consiste en verificar que el programa funcione sin errores, o sea, que haga lo que tiene que hacer.

2.16 Operaciones básicas sobre archivos de disco

Servicios de la interrupción 16h para manejo del teclado.

  • Función 00h. Lee un carácter. Esta función maneja las teclas del teclado de 83 teclas, pero no acepta entrada de las teclas adicionales en el teclado ampliado de 101 teclas. Retorna en al el carácter, ah el código de rastreo si al=0 es una tecla de función extendida.

  • Función 01h. Determina si un carácter está presente.

  • Función 02h. Regresa el estado actual de las teclas shift.

  • Función 10h. Lectura de un carácter del teclado.

  • Función 11h. Determina si está presente un carácter.

    • MOVS. Mueve un byte, palabra o palabra doble desde una localidad en memoria direccionada por SI a otra localidad direccionada por DI.
    • LODS. Carga desde una localidad de memoria direccionada por SI un byte en AL, una palabra en AX o una palabra doble en EAX.
    • STOS. Almacena el contenido de los registros AL, AX, o EAX en la memoria direccionada por SI.

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

Resumen

Se creó un sumador utilizando compuertas lógicas en Minecraft mediante la utilización de redstone y antorchas del mismo material, y se verificó que funcionara correctamente mediante una tabla de verdad.

Objetivo

En esta actividad se busca entender cómo funcionan las compuertas lógicas mediante la construcción de un medio sumador utilizando Minecraft.

Introducción

En la práctica se construirá un circuito electrónico llamado medio sumador en Minecraft, el cual es capaz de sumar dos números binarios y proporcionar el resultado y un valor de acarreo. Este tipo de sumador utiliza una puerta lógica XOR y una puerta lógica AND para llevar a cabo su función. Es importante destacar que esta práctica permitirá comprender mejor el funcionamiento de los sumadores y sus componentes.

Metodología

Compuerta XOR:

La compuerta XOR (también conocida como OR exclusivo) es una compuerta lógica que produce una salida verdadera (1) si sus dos entradas son diferentes entre sí. Si las entradas son iguales, la salida será falsa (0). En otras palabras, la compuerta XOR devuelve 1 si y solo si hay una entrada de 1, pero no ambas entradas de 1. La representación común de la compuerta XOR es con el símbolo ⊕. XOR

Compuerta AND:

La compuerta AND es una compuerta lógica que produce una salida verdadera (1) solo si todas sus entradas son verdaderas (1). Si alguna de las entradas es falsa (0), la salida será falsa (0). En otras palabras, la compuerta AND devuelve 1 solo si todas las entradas son 1. La representación común de la compuerta AND es con el símbolo ∧.

Para construir un medio sumador en Minecraft, se necesitan materiales como polvo de redstone, repetidores de redstone, antorchas de redstone, bloques de cualquier tipo, una compuerta XOR y una compuerta AND. Una vez que se construyen las compuertas, se pueden simular las entradas de 1's y 0's utilizando palancas. Al introducir los valores, se pueden observar las salidas "sum" y "carry" mediante componentes de salida como un pistón y lámparas de redstone. De acuerdo con la tabla de verdad, la lampara en la suma se activará si al menos una de las entradas es 1, mientras que la lámpara de redstone del acarreo solo se activará si ambas entradas son 1. Si las entradas son 0, ninguna de las salidas cambiará. La explicación del funcionamiento es fácil de seguir utilizando la tabla de verdad. AND

Resultados

Medio sumador

Ademas, adjunto un vídeo explicativo del medio sumador: https://www.youtube.com/watch?v=F9aFhWDV8DA

Análisis

La práctica fue exitosa al verificar que el medio sumador funcionaba correctamente siguiendo la tabla de verdad correspondiente. Por lo tanto, se puede concluir que se aplicaron adecuadamente las compuertas lógicas utilizadas en la construcción del circuito.

Conclusiones

Realizar la práctica de simulación de circuitos electrónicos en Minecraft fue muy interesante y útil para comprender mejor el funcionamiento de estos componentes. En mi opinión, es más fácil entender su operación al verlos en acción, en lugar de solo leer la teoría. Aunque la práctica tuvo cierta complejidad, ya que nunca había utilizado redstone para tareas tan complejas, fue divertido y desafiante. En general, considero que fue una experiencia positiva.

Referencias

Práctica #2 - Hola mundo en Ensamblador

Resumen

En esta práctica se profundiza en el conocimiento del funcionamiento del programa "Hola mundo" en Ensamblador, desglosando cada línea de código para comprender detalladamente su funcionamiento y los motivos detrás de cada instrucción utilizada.

Objetivo

En esta práctica se busca comprender el funcionamiento de los registros y otros comandos fundamentales del lenguaje ensamblador, utilizando como ejemplo la creación del programa "Hola mundo". El objetivo es analizar detalladamente cada línea de código para entender mejor el propósito de cada instrucción.

Introducción

En la segunda práctica, nos enfocaremos en el estudio detallado de la sintaxis básica del lenguaje Ensamblador, para lo cual crearemos un programa que imprimirá "Hola mundo" en la pantalla de la computadora. Durante el desarrollo de la práctica, se analizarán minuciosamente los registros que se utilizarán y se explicará el significado de cada instrucción o línea de código completa del programa.

Metodología

Screenshot from 2023-02-24 23-24-49

En la sección ".data" de un programa en Ensamblador se definen los datos y variables a utilizar. En este caso, se declara una cadena de caracteres llamada "msg" que contiene el mensaje "Hola mundo" y un carácter de salto de línea.

La sección ".text" contiene el código principal del programa y es donde se llevan a cabo las operaciones que realiza el programa, como imprimir en pantalla. La etiqueta "_start" indica el punto de entrada del programa y se establecen los valores de los registros "edx", "ecx" y "ebx". "edx" se establece en la longitud de la cadena "msg", "ecx" se establece en la dirección de la cadena y "ebx" en 1 para indicar la salida estándar.

Las instrucciones "mov eax,4" y "int 0x80" realizan la llamada del sistema para escribir la cadena en la salida estándar, mientras que la instrucción "mov eax,1" y "int 0x80" hacen la llamada del sistema para salir del programa.

Resultados

Screenshot from 2023-02-24 23-32-15

Análisis

En esta práctica logramos el objetivo de imprimir en la pantalla el mensaje "Hola mundo", que es un ejemplo clásico en el mundo de la programación. Además, al analizar línea por línea el código en Ensamblador utilizado para este propósito, logramos comprender mejor el funcionamiento de los registros, que son fundamentales en este lenguaje de programación.

Conclusiones

En esta práctica hemos profundizado en nuestro conocimiento del lenguaje ensamblador, gracias a una explicación detallada y documentación útil. A través de nuestro análisis minucioso, pudimos comprender mejor los registros que se utilizan en ensamblador, así como la importancia de ciertas líneas de código, como la que se utiliza para la salida del programa. En general, hemos fortalecido nuestra comprensión y habilidades en ensamblador a través de esta práctica.

Referencias

Práctica #3 - Suma en Ensamblador

Resumen

En esta práctica se aprendió cómo realizar la suma de dos números utilizando la instrucción "add" en lenguaje ensamblador. Esta operación nos permitió obtener el resultado de la suma de manera precisa y eficiente. Con cada práctica, se adquieren nuevos conocimientos sobre las operaciones que podemos realizar en lenguaje ensamblador.

Objetivo

En esta práctica, se realiza una suma de dos números enteros en lenguaje ensamblador mediante el uso de la instrucción 'add'. El objetivo es obtener el resultado de dicha suma y mostrarlo en la consola. Con esto, se busca comprender el funcionamiento de la instrucción 'add' y cómo se puede utilizar en una práctica sencilla para realizar operaciones matemáticas en lenguaje ensamblador.

Introducción

En esta práctica, estaremos explorando las operaciones elementales que se pueden realizar en el lenguaje ensamblador. En particular, realizaremos la suma de dos números y mostraremos el resultado en la salida de consola del sistema. Aunque puede parecer una práctica sencilla, puede ser desafiante dependiendo del resultado que queramos obtener.

Metodología

Screenshot from 2023-02-24 23-25-43

La instrucción 'add' es usada en lenguaje ensamblador para realizar la suma entre dos operandos y almacenar el resultado en el primer operando. La sección '.data' es donde se declaran las variables y datos del programa, en este caso, la variable 'resultado'. La sección '.text' contiene el código principal del programa, en este caso, la función '_start'. En ella, se realiza la suma de dos números utilizando las instrucciones 'mov' y 'add', se convierte el resultado a su valor ASCII y se almacena en la variable 'resultado'. Luego, se usa la función 'write' para imprimir el valor en la consola y se finaliza el programa usando la función 'exit'.

Resultados

Screenshot from 2023-02-24 23-28-21

Los resultados obtenidos en la práctica fueron satisfactorios, ya que se logró imprimir el resultado de la suma de dos números enteros en la salida de consola del sistema. La instrucción 'add' es fácil de entender y esta práctica no requiere de un alto nivel de habilidad y conocimiento. En conclusión, la práctica fue exitosa.

Análisis

En términos generales, la práctica fue exitosa y se logró obtener el resultado esperado en la consola. Sin embargo, se encontró un pequeño obstáculo al querer que el programa soportara la suma de números de dos dígitos en lugar de uno, lo cual requirió un poco más de esfuerzo y comprensión en cuanto a las operaciones matemáticas en lenguaje ensamblador. En definitiva, esta práctica fue una buena introducción para comprender el funcionamiento de las operaciones matemáticas en este lenguaje.

Conclusiones

El programa en sí es simple pero se complica cuando se busca soportar más dígitos en el resultado, ya que hay que convertirlo a su representación ASCII. En mi opinión, esta parte del código es la más difícil. Sin embargo, esta práctica de lenguaje ensamblador te obliga a reflexionar en la solución del problema, algo que no sucede con otros lenguajes, en los que este tipo de problemas son mucho más sencillos de resolver.

Referencias

Práctica #4 - Resta en Ensamblador

Resumen

En esta práctica se abordará la operación de resta de dos números enteros en lenguaje ensamblador, y se imprimirá el resultado en la consola del sistema. A través de esta actividad se podrá adquirir más conocimientos acerca de las distintas operaciones que se pueden llevar a cabo en este lenguaje de programación.

Objetivo

En esta práctica se explorará otra operación básica en lenguaje ensamblador, la resta entre dos números enteros. Se utilizará la instrucción 'sub' para llevar a cabo la operación y se imprimirá el resultado en la consola del sistema. Esta práctica tiene como objetivo ayudar a comprender el funcionamiento de la instrucción 'sub' en el lenguaje ensamblador, a través de una práctica sencilla pero efectiva.

Introducción

Se describe brevemente el funcionamiento del código para obtener el resultado de una resta entre dos números. Exponiendo línea a línea su explicación y mostrando los resultados obtenidos.

Metodología

Screenshot from 2023-02-24 23-26-25

La instrucción 'sub' en lenguaje ensamblador se usa para restar valores en operaciones aritméticas. En la sección de datos, definimos la variable 'resultado' como una cadena de caracteres con un salto de línea y un retorno de carro. En la sección de texto, establecemos el punto de entrada del programa y movemos los valores 8 y 5 a los registros 'eax' y 'ebx', respectivamente. Luego, restamos el valor de 'ebx' de 'eax' y agregamos 48 para obtener el resultado en su valor numérico en ASCII. Guardamos el resultado en la variable 'resultado' y configuramos los registros para llamar a la función del sistema 'write', que mostrará el resultado en la consola. Finalmente, hacemos uso de la función 'exit' para terminar la ejecución del programa.

Resultados

Screenshot from 2023-02-24 23-30-34

Obtenemos el resultado de restar ambos números, obteniendo como resultado el valor de 3, como se puede ver a continuación:

Analisis

En esta práctica, logramos realizar la operación de resta entre dos números enteros y obtener el resultado esperado. Sin embargo, cuando intentamos realizar la resta entre números más grandes y obtener un resultado negativo, la tarea se volvió un poco más complicada. Se puede notar que, aunque la programación de programas simples en otros lenguajes puede ser fácil, en lenguaje ensamblador sigue siendo un reto. A pesar de esto, el objetivo principal de la práctica fue alcanzado y se obtuvieron los resultados esperados.

Conclusiones

El lenguaje ensamblador presenta un nivel de complejidad superior a otros lenguajes de programación, lo que lo hace más difícil de comprender. A pesar de esto, llevar a cabo prácticas como esta puede ayudarnos a continuar explorando este mundo tan diferente al que estamos acostumbrados. Es importante destacar que estas prácticas siempre suponen un reto, ya que el resultado que se espera obtener puede no ser fácil de conseguir.

Referencias

Práctica #5 - Multiplicación en Ensamblador

Resumen

En esta práctica, se aborda la multiplicación de dos números utilizando lenguaje ensamblador, al igual que en prácticas anteriores, pero en esta ocasión, el enfoque está en la operación de multiplicación en lugar de suma o resta. El resultado obtenido se muestra en la consola del sistema, y se busca familiarizarse más con las operaciones aritméticas en este lenguaje.

Objetivo

En este ejercicio se busca desarrollar una comprensión sobre cómo multiplicar dos números en lenguaje ensamblador, haciendo uso de la instrucción 'mul' y sus propiedades. Se aplicará este conocimiento en una práctica corta que permitirá poner en práctica los conceptos aprendidos en la teoría. De esta manera, se podrá fortalecer la comprensión sobre el tema y afianzar los conocimientos adquiridos durante el proceso de aprendizaje.

Introducción

En esta práctica se realizará un programa en el que se multiplicarán dos números y se mostrará su resultado en la consola. Este proceso será similar a las prácticas anteriores en este tema, pero en lugar de sumar o restar, se multiplicará.

Metodología

Screenshot from 2023-02-24 23-27-03

En ensamblador, la instrucción "mul" se utiliza para multiplicar dos números enteros sin signo y almacenar el resultado en un registro específico. El código que se muestra realiza una multiplicación de dos números (3 y 3), almacena el resultado en un registro y luego lo convierte a su representación ASCII para poder mostrarlo en consola. Se utiliza la función de escritura del sistema para mostrar el resultado y luego se llama a la función de salida para salir del programa. Es importante destacar que la sintaxis de la instrucción "mul" varía según la arquitectura de la CPU que se esté utilizando.

Resultados

Screenshot from 2023-02-24 23-30-51

Se obtiene el resultado de multiplicar dos números 3 entre sí, dicho resultado es de 9 y es el mostrado en la imagen siguiente:

Análisis

Esta práctica resultó fácil de llevar a cabo, puesto que no implicaba mucha complejidad en términos de programación y se logró obtener los resultados deseados sin enfrentar dificultades.

Conclusiones

Aunque a simple vista esta práctica puede parecer fácil, al trabajar con ensamblador nos damos cuenta de que incluso las tareas más simples en otros lenguajes pueden ser complicadas. Sin embargo, siempre hay una manera de superar los desafíos que surgen en el proceso y podemos considerar que hemos completado con éxito esta práctica.

Referencias

Práctica #6 - División en Ensamblador

Resumen

En esta práctica, se hizo uso de operadores aritméticos para realizar una operación matemática específica que en este caso fue una división entre dos números.

Objetivo

En esta práctica, hemos explorado el uso del comando "div" en Ensamblador para realizar operaciones matemáticas, específicamente una división entre dos números. Además, se ha profundizado en la comprensión de cómo se realizan estas operaciones utilizando el lenguaje ensamblador.

Introducción

En esta práctica, vamos a crear un programa en lenguaje ensamblador que permita la división de dos números y muestre el resultado obtenido en la pantalla. Para ello, se utilizarán las instrucciones específicas de ensamblador, como la "div", que es la encargada de realizar la operación de división, así como también se explorará la forma en que se pueden mostrar los resultados obtenidos en la consola. En resumen, se trabajará en el desarrollo de habilidades en programación en ensamblador para la realización de operaciones aritméticas más complejas.

Metodología

Screenshot from 2023-02-24 23-27-29

En esta práctica utilizamos la sección .bss para reservar un byte en memoria para nuestra variable de resultado. En la sección principal del código, iniciamos el punto de entrada _start con instrucciones mov para establecer los valores iniciales de los registros bx, dx y ax en 2, 0 y 8 respectivamente. Es importante mencionar que al asignar un valor de 0 al registro dx, este se borra. Luego, utilizamos la función div para realizar la operación de división entre los valores almacenados en ax y bx, que en este caso son 8 y 4, respectivamente. El resultado de la división, que es 4, se almacena en el registro ax. A continuación, sumamos 48 al resultado para convertirlo a su representación ASCII correcta, de lo contrario se imprimiría un valor completamente diferente en la consola. Luego, movemos el resultado del registro ax a la variable de resultado correspondiente utilizando otra instrucción mov. Finalmente, hacemos las interrupciones del sistema necesarias para imprimir el resultado en la consola y terminar la ejecución del programa.

Resultados

Screenshot from 2023-02-24 23-31-01

Es importante destacar que durante el proceso de desarrollo se intentaron diferentes enfoques para agregar un salto de línea al resultado final, sin embargo, cada uno de ellos resultó en errores que impedían la correcta compilación del código. Ante esta situación, se decidió dejar el programa sin el salto de línea y enfocarse en lograr el objetivo principal, que era realizar la división entre dos números y mostrar el resultado en la consola.

Análisis

El programa en Ensamblador que realizamos logró cumplir su objetivo y se imprimió en la consola el resultado esperado, que en este caso fue un 4. Aunque se intentaron diferentes métodos para incluir un salto de línea, finalmente se optó por dejarlo sin él debido a que generaba errores al momento de ensamblar el código. En general, la práctica no presentó mayores complicaciones y se logró realizar la división entre dos números.

Conclusiones

La práctica resultó bastante sencilla, pues sólo se trató de dividir dos números enteros para obtener un resultado también entero. La dificultad se presentó al intentar hacer un salto de línea, ya que al realizar modificaciones al código, éste fallaba al ensamblarlo. Sin embargo, a pesar de esta dificultad, se logró cumplir con el objetivo de la práctica. En mi opinión personal, el proceso resultó satisfactorio.

Referencias

Maldonado, G., & Perfil, V. T. M. (s. f.). 1. División en lenguaje ensamblador. https://linterfazgmo.blogspot.com/2019/02/1-division.html

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 se utiliza para desplazar los bits hacia la izquierda de un operando mediante un desplazamiento lógico. Los bits menos significativos se rellenan con ceros mientras que los bits más significativos se pierden. Esto se puede utilizar para operaciones aritméticas como multiplicación o división por potencias de dos. En esta práctica, crearemos un programa en ensamblador que utilice un operando y un contador para realizar el desplazamiento de bits hacia la izquierda.

Metodología

image

El código en ensamblador comienza con la definición de las secciones .data y .bss, donde se definen las variables necesarias para el programa. La sección .text es el punto de entrada del programa, donde se inicia la ejecución.

En este caso, el programa utiliza la instrucción shl para desplazar bits hacia la izquierda en el registro ebx, lo que equivale a multiplicar por dos. Luego, se agrega el valor ASCII del número 4 al registro ebx y se almacena en la variable resultado.

Para imprimir el resultado, se llama a la función write del sistema y se utiliza el número 4 como argumento. Luego se llama a la función exit y se invoca la interrupción del sistema con la instrucción int 0x80.

Finalmente, se utiliza la función write y exit para imprimir un salto de línea y terminar el programa con la función exit. Los valores 1 y 0 se cargan en los registros eax y ebx antes de salir del programa.

Resultados

image

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 de desplazamiento hacia la izquierda en Ensamblador se completó con éxito, sin encontrar ningún problema durante su ejecución. La práctica resultó sencilla, especialmente al tener acceso a la tabla ASCII, lo que permitió imprimir los caracteres requeridos de manera adecuada. En general, la práctica fue fácil de seguir y completar con éxito.

Referencias

Desplazamiento a la izquierda en ensamblador. (s. f.). Recuperado 3 de marzo de 2023, de http://www.atc.uniovi.es/telematica/2ac/Apuntes-y-Ejercicios/Instrucciones-Aritmetico-Logicas-IA-32.pdf

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

La instrucción "shr" en lenguaje ensamblador es una operación que desplaza los bits de un operando hacia la derecha de manera lógica, lo que significa que los bits menos significativos se pierden y se rellenan con ceros los bits más significativos. Esta operación puede ser útil para realizar cálculos aritméticos como multiplicaciones o divisiones por potencias de dos. En esta práctica, vamos a crear un programa en ensamblador que realiza el desplazamiento hacia la derecha utilizando un operando y un contador.

Metodología

image

En esta práctica en Ensamblador, vamos a realizar un programa que haga uso de la instrucción shr, la cual permite realizar un desplazamiento lógico hacia la derecha de los bits de un operando. Primero, definimos las variables necesarias para la ejecución del programa, y luego iniciamos la ejecución del programa. En este caso, movemos el valor 2 al registro ebx, y realizamos un desplazamiento hacia la derecha en el mismo registro utilizando la instrucción shr ebx, 1, lo que equivale a dividir por 2. De esta manera, el registro ebx posee un valor de 1. A continuación, sumamos 48 al valor de ebx con la instrucción add ebx, 48, para que corresponda al valor ASCII del número 1. Luego, almacenamos el valor del registro ebx en nuestra variable resultado con la instrucción mov [resultado], ebx.

Finalmente, hacemos uso de la función write del sistema para imprimir el resultado, utilizando el número 4. Llamamos a la función exit con el número 1, e invocamos la interrupción en el sistema con int 0x80 para llamar a la función de escribir. Después, llamamos al salto de línea con las funciones write y exit, y terminamos el programa con la función exit para finalizarlo, cargando los valores 1 y 0 en los registros eax y ebx antes de salir.

Resultados

image

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

El programa realizado tuvo éxito en el desplazamiento hacia la derecha sin ninguna dificultad. La práctica fue simple ya que el código era casi idéntico al anterior, con la única diferencia en la instrucción utilizada para desplazar.

Referencias

Desplazamiento a la derecha en ensamblador. (s. f.). Recuperado 3 de marzo de 2023, de http://www.atc.uniovi.es/telematica/2ac/Apuntes-y-Ejercicios/Instrucciones-Aritmetico-Logicas-IA-32.pdf

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

La instrucción rol en Ensamblador es una herramienta que permite realizar un desplazamiento rotatorio hacia la izquierda de los bits de un operando. Es decir, los bits se moverán una cantidad determinada de posiciones hacia la izquierda y el bit más significativo se moverá al flag C y al bit menos significativo del operando. Esta instrucción puede ser útil para realizar operaciones aritméticas como multiplicaciones o divisiones por potencias de dos, tanto con signo como sin signo. Con el objetivo de entender mejor su funcionamiento, se llevará a cabo una práctica en la que se utilizará esta instrucción.

Metodología

image

En este programa en Ensamblador, se utiliza el comando rol para realizar una rotación circular a la izquierda de los bits en el registro BL. Posteriormente, se suma 48 a dicho registro para convertir el valor al correspondiente en la tabla ASCII y se almacena el resultado en la variable definida en la sección .bss.

Luego, se llama a la función write del sistema para imprimir el resultado en pantalla y a la función exit para salir del programa. Se utiliza la interrupción del sistema int 0x80 para invocar la función de escribir. Se imprime un salto de línea utilizando la función write y se termina el programa con la función exit. Por último, se cargan los valores 1 y 0 en los registros eax y ebx antes de salir.

Resultados

image

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

J., & Profile, V. M. C. (s. f.). Ensamblador I: 6.4. CORRIMIENTO Y ROTACION. https://ensam1.blogspot.com/2005/09/64-corrimiento-y-rotacion.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

En Ensamblador, la instrucción ror se utiliza para rotar hacia la derecha los bits de un operando. Durante la rotación, el bit menos significativo del operando se desplaza al bit más significativo y al flag C. El comando ror puede ser muy útil para realizar operaciones aritméticas como multiplicaciones o divisiones por potencias de dos con o sin signo. En resumen, la instrucción ror permite realizar desplazamientos rotatorios hacia la derecha en lugar de hacia la izquierda, lo que puede ser útil en diferentes situaciones de programación en Ensamblador.

Metodología

image image

En la sección .data, definimos las variables que se usarán en el programa, que en este caso son solo para un salto de línea.

En la sección .bss, se define la variable resultado, la cual al ser almacenada en esta sección, se reserva un byte en memoria para guardar la variable.

En la sección .text, se define el punto de entrada del programa y se inicia su ejecución. Primero, se mueve el valor 128 al registro BL con la instrucción mov bl, 128. Luego, se realiza una rotación circular hacia la derecha en el registro BL con la instrucción ror bl, 1, moviendo el bit menos significativo al flag C y al bit más significativo del operando. Posteriormente, se suma 48 al registro BL para convertir el valor a su equivalente en la tabla ASCII.

Después, se almacena el valor del registro BL en la variable resultado con la instrucción mov [resultado], bl.

Para imprimir el resultado, se utiliza la función write del sistema con el número 4. Luego se llama a la función exit con el valor 1 para finalizar el programa, y se invoca la interrupción del sistema con int 0x80 para llamar a la función de escritura. Finalmente, se llama a la función write y exit de nuevo para imprimir un salto de línea y terminar el programa con la función exit, cargando los valores 1 y 0 en los registros eax y ebx antes de salir.

Resultados

image

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

J., & Profile, V. M. C. (s. f.). Ensamblador I: 6.4. CORRIMIENTO Y ROTACION. https://ensam1.blogspot.com/2005/09/64-corrimiento-y-rotacion.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 este ejercicio se utiliza la entrada del teclado para obtener datos que se almacenan en variables durante la ejecución del programa. Esto permite al usuario interactuar con el programa en tiempo real y proporciona una experiencia más dinámica. Para obtener los datos del teclado, se utiliza llamadas al sistema para realizar operaciones de entrada/salida en la consola. En comparación con prácticas anteriores, donde los datos se incluían en el código, esta práctica es más flexible y permite una mayor personalización de la entrada de datos.

Metodología

image image

En este programa se definen variables y constantes en la sección .data para ser usadas durante la ejecución del programa. La variable "numero" será utilizada para almacenar el número ingresado por el usuario.

En la sección .text, se inicia la ejecución del programa. Primero se utiliza la llamada al sistema para imprimir un mensaje en la salida estándar, utilizando los registros eax, ebx, ecx y edx para especificar el mensaje a imprimir y su longitud. Luego se repite este proceso con otras variables y mensajes.

Finalmente, se utiliza la función exit para terminar el programa y se cargan los valores 1 y 0 en los registros eax y ebx antes de salir. En resumen, el programa utiliza llamadas al sistema para interactuar con el usuario y mostrar mensajes en la consola.

Resultados

image

Análisis

Con el código que se presenta en esta práctica, se introduce una nueva metodología para programar en ensamblador que nos permite interactuar con el usuario para que este pueda ingresar información en tiempo de ejecución. Esto amplía las posibilidades de creación de programas en ensamblador, permitiéndonos crear aplicaciones más complejas y personalizadas que pueden ser utilizadas por los mismos usuarios. Esta nueva metodología sustituye la forma anterior de trabajar, en la que los datos eran predefinidos en el código y limitaban la interacción del usuario con el programa.

Conclusiones

La práctica se ha realizado satisfactoriamente y se ha adquirido conocimiento sobre cómo obtener datos a través de la entrada del teclado por parte del usuario. Ahora, es posible crear programas más avanzados y también mejorar los anteriores incorporando la funcionalidad de entrada por teclado.

Fuentes bibliográficas

Ensamblador - Introducir un numero por el teclado. (s. f.). https://www.lawebdelprogramador.com/foros/Ensamblador/523807-Introducir-un-numero-por-el-teclado.html

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 son instrucciones que siempre se ejecutan y no están sujetas a ninguna condición. Estas instrucciones permiten al programa saltar a una nueva dirección y se usan para crear estructuras como bucles, subrutinas, condicionales y otros tipos de estructuras de control de flujo.

Metodología

image

En este código, empezamos definiendo una sección de datos donde se crean dos cadenas de texto con "Etiqueta 1" y "Etiqueta 2" seguidas de caracteres especiales para saltar de línea y terminar la línea. También se definen dos constantes para conocer la longitud de las cadenas en el futuro. Luego, se define una sección de memoria no inicializada.

El programa inicia con la etiqueta "_start" y salta incondicionalmente a la sección etiqueta2, la cual imprime "etiqueta 2" en la pantalla. La sección etiqueta1, por su parte, solamente imprime "etiqueta 1".

Usando el número 4, llamamos a la función write del sistema para imprimir el resultado y con el número 1, llamamos a la función exit. Finalmente, la interrupción 0x80 se invoca para llamar a la función de escritura del sistema. Después, se llama a la función write y exit para hacer un salto de línea y terminar el programa con la función exit, cargando los valores 1 y 0 en los registros eax y ebx antes de salir.

Resultados

image

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

Saltos incondicionales. (s. f.). orga blog. Recuperado 17 de marzo de 2023, de http://orga.blog.unq.edu.ar/wp-content/uploads/sites/5/2019/10/orga_apunte_saltos.pdf?ref=ciberseguridad-blog#:~:text=Los%20saltos%20disponibles%20se%20clasifican%20en%20condicionales%20e%20incondicionales.&text=La%20instrucci%C3%B3n%20de%20salto%20incondicional,CALL%20no%20modifica%20la%20pila.

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 un tipo de instrucciones en programación que permiten al programa saltar a una nueva dirección solo si se cumple cierta condición. Estos son útiles para crear estructuras de selección, como "if" o "switch", donde se toma una decisión basada en si una condición se cumple o no.

Metodología

image

En primer lugar, en la sección .data definimos una cadena de caracteres que almacenará un mensaje de error y determinamos su longitud en la variable lonmsg. Además, reservamos un byte de memoria en la sección .bss para almacenar el resultado de la división.

Luego, en el punto de entrada de nuestro programa, movemos los valores necesarios para realizar la operación aritmética a los registros correspondientes. Realizamos una comparación para verificar si el divisor es cero. Si es así, se salta a la etiqueta "escero" y se muestra el mensaje de error. En caso contrario, se realiza la división mediante la instrucción "div ebx". El resultado se convierte en un carácter ASCII correspondiente al dígito numérico obtenido, que se almacena en la memoria reservada en la sección .bss.

Finalmente, imprimimos el resultado en la pantalla utilizando la función write del sistema con el número 4 y llamamos a la función exit con el valor 1. Invocamos la interrupción del sistema con int 0x80 para realizar estas acciones. Después de esto, agregamos un salto de línea y finalizamos el programa utilizando la función exit y cargando los valores 1 y 0 en los registros eax y ebx.

Resultados

image

Análisis

La práctica se llevó a cabo de manera satisfactoria, logrando obtener los resultados deseados y demostrando cómo los saltos condicionales pueden ser utilizados para prevenir errores en nuestro código. En este caso, se utilizó un salto condicional para desviar el flujo del programa y mostrar un mensaje de error en caso de que se intente realizar una división entre cero. Esto permitió asegurar el correcto funcionamiento del programa y evitar errores indeseados.

Conclusiones

Durante esta práctica aprendimos a utilizar diferentes instrucciones en ensamblador para construir un programa que hace uso de saltos condicionales para controlar su flujo. Estos saltos son especialmente útiles para desviar la ejecución del programa en función de las condiciones que se establezcan. En conclusión, los saltos son una herramienta fundamental en la programación en ensamblador y su uso puede ser muy beneficioso para el desarrollo de programas más complejos.

Referencias

404 Not Found. (s. f.). http://sagitario.itmorelia.edu.mx/mfraga/materias/li/recomendaciones+MSP430.pdf

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

En esta práctica vamos a utilizar la entrada por teclado para obtener dos números ingresados por el usuario y luego realizar una división entre ellos. Para lograr esto, vamos a combinar lo aprendido en las prácticas #6 y #11 y utilizar los conocimientos adquiridos para crear un programa que sea capaz de tomar los números ingresados por el usuario y procesarlos mediante código ensamblador.

Metodología

image

En la práctica, se definen variables en las secciones .data y .bss del programa. En la sección .data, se definen dos mensajes de texto, uno para solicitar un número al usuario y otro para mostrar un mensaje de error si se ingresa cero. En la sección .bss, se definen dos variables, "Numero" y "resultado", que se utilizarán para almacenar los valores ingresados por el usuario y el resultado de la división.

El programa comienza en el punto de entrada "_start". Primero, se muestra el mensaje de texto para solicitar un número al usuario, y luego se lee un solo byte desde la entrada estándar y se almacena en la variable "Numero". Después, el programa convierte el valor ingresado de ASCII a entero y verifica si es cero. Si es cero, el programa salta a la etiqueta "escero" y muestra el mensaje de error en la salida estándar. Si el valor ingresado es distinto de cero, el programa divide el valor por dos y almacena el resultado en la variable "resultado". Luego, convierte el resultado de nuevo de entero a ASCII y lo muestra en la salida estándar.

Finalmente, se llama a la función del sistema para imprimir una nueva línea y se utiliza la función exit para finalizar el programa, cargando los valores 1 y 0 en los registros eax y ebx. En general, este programa utiliza los saltos condicionales para evitar errores en caso de que se ingrese un valor cero y realiza una división si se ingresa un número distinto de cero.

Resultados

image

Análisis

En esta práctica, logramos obtener los resultados deseados al aplicar los conocimientos adquiridos en prácticas previas. Aunque el proceso tuvo cierta complejidad, sobre todo con la conversión del número de entrada de ASCII, finalmente pudimos culminar con éxito la tarea.

Conclusiones

Durante esta práctica pudimos experimentar con las diversas instrucciones que se utilizan en ensamblador para construir un programa que hace uso de saltos condicionales para controlar su flujo. Estos saltos son muy útiles para dirigir la ejecución del programa en función de las condiciones establecidas. En resumen, los saltos son esenciales para la programación en ensamblador y su implementación puede ser muy ventajosa para desarrollar programas más sofisticados.

Referencias

Maldonado, G., & Perfil, V. T. M. (s. f.). 1. División en lenguaje ensamblador. https://linterfazgmo.blogspot.com/2019/02/1-division.html