Tema I Introducción al lenguaje ensamblador - Crypto-ch4r/Lenguajes-de-Interfaz- GitHub Wiki
1.1 - Importancia de programación en lenguaje ensamblador
Definiciones importantes
Lenguajes de computadora.- Los lenguajes de computadora, son una sintaxis codificada usada por programadores para comunicarse con ella. En la siguiente imagen podemos apreciar algunos ejemplos de ellos.
Transistor.- Un transistor es un dispositivo semiconductor. Este se encuentra presente en todos los aparatos tecnológicos (radios, teléfonos, computadoras, etcétera). Permiten el paso de una señal en respuesta a otra. Se fabrican con silicio, germanio, aluminio y aleaciones de estos mismos.
¿Qué es el lenguaje ensamblador y cuál es su importancia?
Assembler es un lenguaje de programación de bajo nivel que se usa en microprocesadores. Su estructura se acerca bastante a lo que es el lenguaje máquina. El primer lenguaje ensamblador surgió en los 50's gracias a Kathleen Booth marcando un antes y un después en el mundo de la programación ya que gracias al surgimiento del primer lenguaje, desde ese momento fue más fácil realizar programas y de ahí su importancia en la historia de la programación.
Con el paso de los años, dejó de usarse gracias al surgimiento de los lenguajes de alto nivel aunque eso no significa que en la actualidad sea irrelevante. Su importancia en la actualidad radica en que de esta manera estamos trabajando directamente con el microprocesador y podemos optimizar el rendimiento del hardware y entenderlo de una manera más profunda lo cual puede ser de utilidad para la investigación, desarrollo y aplicación de nuevas tecnologías. . Adicionalmente, en este lenguaje se pueden realizar distintos programas que lenguajes de alto nivel no pueden realizar.
:warning: NOTA: :warning: Ningún lenguaje ensamblador es igual. Cada procesador tiene sus instrucciones y sintaxis que lo caracteriza y diferencia de otros. Un procesador Intel no tiene las mismas instrucciones que un procesador AMD.
Ley de Moore
Gordon E. Moore, el cofundador de Intel, fue quien formulo esta ley empírica en la que se establece que aproximadamente cada dos años el número de transistores de un microprocesador se duplica y se aplica a cualquier sistema motorizado. En otras palabras, cada dos años se reduce el tamaño de los transistores para agregar más. No obstante en la actualidad ha surgido un problema... El estancamiento de la Ley de Moore debido al límite físico de la tecnología actual.
El silicio y el germanio que son los materiales más utilizados para hacer estos transistores ya no se puedan compactar más y es posible que no se pueda realizar el siguiente salto por ello es que empresas como Google y Microsoft están trabajando en utilizar grafeno en lugar de silicio o germanio.
1.2 El procesador y sus registros internos.
Componentes principales de una computadora
Unidad Central de Procesamiento (CPU): Es el cerebro de la computadora, se encarga de realizar calculos y ejecutar programas. Lo que tenemos aquí arriba es un diagrama representando los componentes del CPU, se puede dividir en tres partes basándonos en su funcionalidad:
- Unidad de control: Completa el despliegue de todo el proceso de procesamiento de datos.
- Unidad de operación lógica: Completa cada instrucción con el fin de obtener el resultado final deseado del programa.
- Unidad de almacenamiento: Es la responsable de almacenar los datos originales y el resultado de la operación.
Tarjeta madre
Lo que se puede ver en la imagen de arriba es la tarjeta madre de una computadora. Es la pieza principal de los circuitos a la que se conectan otras piezas y crean un conjunto. La tarjeta madre permite que estos componentes se conecten y comuniquen entre sí, por ello, si la tarjeta madre se daña estas en un grave problema.
Componentes de la tarjeta madre y de la computadora
-
Unidades ópticas como DVD y CD-ROM: Es un dispositivo que permite leer y grabar archivos en discos de DVD, CD y Blu-ray en una computadora. Este posee unos lentes que proyectan ondas electromagnéticas, que son responsables de la lectura y escritura de la información en los CD's o DVD. Son más común en PC's de escritorio. En las laptops poco a poco se han dejado de implementar con el paso de los años porque se piensa que es un hardware innecesario ya que hoy en día el USB y el almacenamiento en nube facilitan el guardado de información.
-
Tarjetas de vídeo (GPU): Es un circuito electrónico especializado que acelera la creación y renderización de imágenes, vídeos y animaciones. Realiza cálculos matemáticos rápidos, liberando a la CPU para que pueda realizar otras tareas. Hay dos tipos, las tarjetas gráficas integradas que se localizan directamente en la CPU y comparten la misma memoria RAM y las que son dedicadas, estas tienen su propia tarjeta y memoria.
-
Tarjetas de sonido: Se trata de un controlador que puede insertarse en una ranura ISA (o PCI para las más recientes). Aunque en la actualidad cada vez son más frecuentes las placas madre que incluyen su propia tarjeta de sonido. Permite administrar la entrada y salida del audio.
-
Disco duro: Es una unidad de hardware donde se almacenan los archivos y programas permanentes de la computadora. Toda computadora posee uno de manera interna, pero también hay discos duros externos que pueden usarse para ampliar el almacenamiento de una computadora. Existen dos tipos:
-
HDD: Es el tipo "más tradicional" de disco duro. Está compuesto por discos magnetizados (también llamados platos) que giran rápidamente normalmente entre 5400 y 15000 RPM. Cuanto más rápido gira el disco magnético, más rápido puedes acceder a la información que contiene.
-
SSD: Las unidades de estado sólido son el tipo de disco duro más nuevo, son usados en laptops de alta gama y en todos los teléfonos inteligentes y tabletas. Usan una memoria flash como los flash USB. Aquí en lugar de imanes, se usan semiconductores que almacenan datos mediante la alteración del estado eléctrico de los billones de circuitos en las SSD. Tienden a durar más que las HDD y son más rápidos.
-
Procesador: Es el cerebro del sistema, tal y como su nombre lo indica, procesa todo lo que ocurre en la PC y ejecuta todas las acciones que existen. Este componente es parte del hardware de muchos dispositivos, no solo de las PC. Están hechos de silicio y van en el socket sobre la placa madre. Los fabricantes de procesadores de PC más populares son Intel y AMD.
-
Tarjetas de memoria (RAM): También conocida como memoria de acceso aleatorio, es la memoria de la computadora que se encarga de almacenar los datos que un programa necesita mientras se ejecuta. Con ser de acceso aleatorio se refiere a al tipo de almacenamiento de datos que permite que se pueda acceder a los datos almacenados en cualquier orden y no en secuencia como los discos, cintas magnéticas, etc.
-
Fuente de poder: Proporciona energía a todos los componentes de la computadora.
-
Pantalla: Muestra la información en la computadora.
-
Teclado y mouse: Son los dispositivos de entrada principales para interactuar con la computadora.
Resumen histórico de los procesadores.
-
Década de 1950 y 1960: Los primeros procesadores surgieron en la década de 1950 y 1960, y eran enormes dispositivos electrónicos con pocas capacidades y velocidades de procesamiento limitadas. Estos primeros procesadores eran utilizados en computadoras mainframe y eran operados por personal especializado. Previamente a estos acontecimientos, en el año 1947 se inventa el transistor. Hacia finales de la década de los 50's surge el circuito integrado en el año 1958, inventado por Jack Killby
-
Década de 1970: Durante la década de 1970, se hicieron diversos avances tecnológicos relacionados con los procesadores, estos se hicieron más pequeños y más accesibles para el público en general. Se introdujo la arquitectura de procesador de 8 bits, un hito que permitió una mayor simplicidad en la programación y una mayor accesibilidad a las computadoras personales.
Durante esta década, el Intel 4004 fue lanzado en 1971 y fue el primer procesador de computadora independiente. Era un chip de 4 bits y tenía 2.300 transistores. Tanto Central Air Data Computer como Texas Instruments TMS 1000 se crearon en esa época, pero no se comercializaron como un procesador individual. En el año 1971 surgió el boom por los videojuegos, siendo el juego de pingpong uno de los primeros en surgir. Los primeros juegos digitales eran creados más por curiosidad científica que como negocio. Dos hombres, Ralph Baer (el padre de la primera consola de videojuegos Odyssey) y Nolan Bushnell cambiarían esta visión de los videojuegos.
Para finales de la década, Intel lanzó el chip 8088 en 1979. El 8088 fue un procesador de 16 bits y contenía 29.000 transistores. Este chip fue elegido para la primera computadora personal IBM.
-
Década de 1980: La década de 1980 fue un período de rápido crecimiento para los procesadores. Se introdujo la arquitectura de procesador de 16 bits, lo que permitió una mayor capacidad de procesamiento y mejoró el rendimiento de las computadoras personales. Además, las computadoras personales para el hogar y la oficina hicieron su aparición, y los procesadores se convirtieron en un componente esencial de la vida cotidiana.
-
Década de 1990: La década de 1990 vio una nueva ola de avances en la tecnología de los procesadores. Se introdujo la arquitectura de procesador de 32 bits, lo que permitió un mayor rendimiento y eficiencia. Además, se desarrollaron los primeros procesadores multimedia, un hito que permitió la edición de vídeo y audio en computadoras personales.
El Intel Pentium fue lanzado en 1993 como un procesador de 32 bits con 3,21 millones de transistores. Esto supuso para la compañía estar en lo más alto del sector y convertirse en la marca de procesadores por excelencia durante varios años. Todos los ordenadores querían llevar en su interior un procesador Intel Pentium. Dos años más tarde la competencia de Intel, AMD, lanzó su chip AM5x86, el cual tenía un rendimiento comparable a los procesadores Pentium, pero era capaz de ser instalado en placas 486 más antiguas.
- Década de 2000: La década de 2000 fue un período de gran evolución en la tecnología de los procesadores. Se introdujeron los procesadores de 64 bits, lo que permitió una mayor capacidad de procesamiento y mejoró el rendimiento de las aplicaciones de alto rendimiento. Además, los procesadores empezaron a integrarse en una amplia variedad de dispositivos electrónicos, como teléfonos móviles, cámaras digitales y televisores. También se desarrollaron procesadores multicore, un hito que permitió un mayor rendimiento y eficiencia energética.
Durante esta década, el Intel Pentium M fue lanzado en 2003 y se diseñó pensando específicamente en dispositivos móviles. El procesador está integrado con la red Intel PRO/Wireless 2100 y utiliza menos energía para permitir una mayor duración de las baterías.
Años más tarde, en el 2004, Intel lanzó su primer procesador de 64 bits para la línea Xeon (Nocona). Con este lanzamiento apareció la arquitectura 64-bit x86, que es la que se utiliza en los ordenadores de hoy en día. Dos años más tarde, Intel inauguró la era de chips con dos y cuatro núcleos con los Intel Core 2 Duo. Gracias a estos procesadores, el rendimiento de los anteriores Pentium 4 aumentó considerablemente.
En el 2008 había muchos aparatos que pedían a gritos ser más inteligentes. Intel lanzó entonces los primeros procesadores ATOM, especialmente diseñados para ultra-portátiles y smartphones.
El POWER 7 de IBM fue lanzado en 2009 y contiene 1.200 millones de transistores en un chip de gran tamaño que posee entre 4 y 8 núcleos. Y como última gran innovación de Intel en la decada de los 2000, en el 2010, lanzó los primeros chips con gráfica integrada.
- Actualidad:
Desde entonces, los procesadores han continuado evolucionando a un ritmo acelerado, con nuevas tecnologías como la inteligencia artificial y la nube llevando a una mayor capacidad y eficiencia. Hoy en día, es posible encontrar procesadores desde 2 núcleos hasta 16 núcleos.
En el mercado actual, los líderes en procesadores son Intel y AMD. Ambas empresas ofrecen una amplia gama de procesadores para una amplia variedad de aplicaciones, incluyendo computadoras de escritorio, portátiles y servidores. Además, hay otras empresas importantes en el mercado, como Qualcomm en el mercado de procesadores móviles y Nvidia en el mercado de procesadores gráficos.
Evolución de los transistores.
El transistor fue inventado en 1947, construido por William Shockley, John Bardeen y Walter H. Brattain en 1947, trabajaba como un tubo de vacío que permitía amplificar pequeñas corrientes eléctricas de una manera muy simple.
Los científicos hicieron primero un sánduche de materiales semiconductores y luego aplicaron una pequeña corriente, o flujo de electrones, en su región media (llamada base). La corriente alteraba las propiedades de conductividad del material y permitía que un número relativamente grande de electrones fluyera entre las capas externas del semiconductor (llamadas emisor y colector). Rápidamente se convirtió en un componente clave en la electrónica.
Por un precio relativamente bajo, los transistores hacían su trabajo sin el calor, tamaño y desgaste de energía de los tubos de vacío. Los tres físicos de Bell ganaron el Premio Nobel por su descubrimiento en 1956. En un principio, los transistores se utilizaron en aplicaciones de amplificación y conmutación, pero pronto se descubrió que también podían ser usados para crear circuitos lógicos básicos.
A partir de ahí, los ingenieros electrónicos comenzaron a desarrollar compuertas lógicas basadas en transistores. Las compuertas lógicas son elementos básicos que pueden realizar operaciones lógicas, como la negación (NOT), la conjunción (AND) y la disyunción (OR), utilizando señales eléctricas. Estas compuertas lógicas se combinaron para crear circuitos más complejos, como los flip-flops, que son dispositivos de memoria digital básicos que pueden mantener un bit de información.
A medida que la tecnología avanzó, los flip-flops y las compuertas lógicas se integraron en chips más grandes y complejos, conocidos como microprocesadores. Un microprocesador es un chip que contiene una CPU completa, incluida la arquitectura de la CPU, las unidades de ejecución, los registros y la unidad de control. La combinación de flip-flops, compuertas lógicas y transistores en un solo chip permitió a los ingenieros crear procesadores más pequeños, más rápidos y más eficientes, lo que dio lugar a una revolución en la tecnología de la computación.
Zoom al CPU
Para comprender un poco mejor el CPU y su funcionamiento, es necesario que hagamos un zoom para poder analizar lo que la compone junto con sus partes principales. Esta información complementa lo que habíamos visto previamente del CPU en esta wiki. Por ello, a continuación se presentan las partes principales de un CPU:
-
Arquitectura de la CPU: La arquitectura de la CPU es un conjunto de componentes y reglas que definen la forma en la que trabaja la CPU. Básicamente esto define como debe de funcionar, como comunicarse con el resto de los componentes, como procesar datos, como almacenar datos, etc. A lo largo de la historia han surgido diversas arquitecturas importantes, no obstante, estas se analizaran más adelante en esta wiki.
-
Unidades de ejecución: Son componentes internos de la CPU. Las unidades de ejecución se encargan de realizas tareas específicas en el procesamiento de los datos y la ejecución de instrucciones además de que llevan a cabo operaciones matemáticas y lógicas para realizar cálculos y tomar decisiones, dentro de estas unidades de ejecución se encuentra la ALU (Unidad Aritmética Lógica).
-
Registros: Son pequeñas áreas de memoria en el CPU, se utilizan para almacenar y transferir datos. Se caracterizan por ser más rápidos que la memoria principal, son usados para almacenar datos que son utilizados de manera frecuente para el procesamiento de datos y ejecución de instrucciones. Sus tipos serán analizados más adelante en esta wiki.
-
Buses de datos: Son canales de comunicación de un sistema, estos canales son los que permiten que haya una comunicación e intercambio de datos entre los diferentes componentes que conforman el CPU en el cual se encargan de transferir la información entre el CPU, el disco duro/los duros, la tarjeta gráfica, etc.
-
Unit Control: También conocida como Unidad de Control, es otro componente interno de la CPU. Su tarea, tal y como lo podemos intuir por su nombre, es controlar y coordinar el procesamiento de datos y la ejecución de instrucciones.
Entre sus distintas tareas podemos ver que es quien se encarga de interpretar las instrucciones del programa así como también determina el cómo deben de ser procesadas y ejecutadas. Además de esta tarea de interprete, la Unidad de Control se encarga de generar señales de control para realizar las operaciones requeridas y controla el acceso a la memoria y los registros.
- Cache: La cache es una pequeña área de memoria en el CPU que se utiliza para guardar la información de programas e instrucciones que se utilizan de manera frecuente. Su propósito de utilización es el reducir el tiempo de acceso a la memoria así como también incrementar el rendimiento de nuestro CPU. Cuando se necesita acceder a información o instrucciones, la CPU primero revisa la memoria cache, de no ser así procederá a checar en la memoria principal. En una computadora, podemos encontrar la cache de nivel 1, nivel 2 y L3 (L1, L2, L3). Cada una de ellas se caracteriza por tener cierto tamaño y velocidad siendo la más rápida pero la más pequeña la L1.
Arquitecturas computacionales a lo largo de la historia.
- Arquitectura de Von Neumann: También conocida como modelo de Von Neumann o arquitectura Princeton es una arquitectura de computadoras basada en la descrita en 1945 por el matemático y físico John von Neumann. Fue la primera arquitectura formal y se utiliza como modelo básico en la mayoría de las computadoras modernas. Su diagrama se puede apreciar a continuación, donde podemos ver que esta arquitectura se caracteriza por tener una memoria principal, una unidad E/S y un CPU.
- Arquitectura Harvard: Es una variante de la arquitectura de Von Neumann que surgió en la década de 1950 bajo el liderazgo de Howard Aiken, se diferencia de ella en que tiene dos buses separados para direcciones y datos permitiendo de esta manera una mayor eficiencia de la memoria y por ende, también de la ejecución de las instrucciones. En la actualidad, la mayoría de los procesadores implementan esto por motivos de rendimiento. En la siguiente imagen podemos apreciar un diagrama de esta arquitectura.
- Tercera generación de computadoras: Sucediendo en los años 1960 a 1970, en estos años se introdujeron los primeros circuitos integrados y las computadoras comenzar a utilizar sistemas operativos. Los circuitos integrados combinaban varios componentes electronicos como transistores, condensadores, entre otros. Estos circuitos superaban a los tubos de vacio y a los transistores, tanto en costo como en rendimiento. Esto se ha seguido usando hasta la generación actual.
- Arquitectura CISC: Complex Instruction Set Computer (CISC) o en español, Computadora de Conjunto de Instrucciones Complejas es una arquitectura que como su nombre lo indica, usa un conjunto complejo de instrucciones para mejorar la facilidad de programación y la realización de múltiples tareas a la vez. Fue muy popular en los años 60's y 70's.
- Arquitectura RISC: Reduced Instruction Set Computer (RISC) o en español, Computadora de Conjunto de Instrucciones Reducidas es una arquitectura de computadoras que surgio en la decada de los 80's, se caracteriza por tener un conjunto reducido de instrucciones (tal como su nombre lo indica) para de esta manera mejorar la velocidad y eficiencia de la CPU. Es utilizada en muchos procesadores de la época moderna.
- Arquitectura VLIW: Very Long Instruction Word (VLIW) o en español, Palabra de Instrucción Muy Larga es una arquitectura de computadora que implementa una forma de paralelismo a nivel de instrucción. Se caracteriza por poseer una instrucción muy larga que contiene información sobre múltiples operaciones. Las ventajas de esta arquitectura es que simplifican bastante la arquitectura y pueden operar con menor potencia y menor consumo.
-
Arquitectura EPIC: Explicitly Parallel Instruction Computing (EPIC) o en español, Procesamiento de Instrucciones Explícitamente en Paralelo es una arquitectura de procesador que como su nombre lo indica, se enfoca en la paralelización explícita de instrucciones. Su objetivo era aumentar la capacidad de los microprocesadores para ejecutar instrucciones de software en paralelo mediante el uso del compilador. Fue utilizado por Intel y HP para el desarrollo de la arquitectura de Intel IA-64 y se ha implementado en la línea de procesadores de servidor Intel Itanium e Itanium 2.
-
Arquitectura x86: Esta arquitectura se utiliza en la mayoría de las computadoras personales y está detrás de la mayoría de los sistemas computacionales del mundo, se ha vuelto muy popular debido a su compatibilidad con una amplia gama de software. Es una familia de instrucciones de procesamiento agrupadas en un conjunto que se le conoce como arquitectura. Fue desarrollada por Intel a finales de los años 70 basándose en el microprocesador 8086 y el 8088.
A partir de su introducción al mercado, comenzó a ser el estándar para la fabricación de CPU, pues permite generar conjuntos de instrucciones más amplios y complejos. Un CPU x86 moderno realiza cómputos de 64 bits. Es decir, estos almacenan piezas de datos en 64 bits, lo cual dobla la capacidad de 32 bit y triplica la de uno de 16 bit.
Tipos de unidades de ejecución
-
Unidad Aritmética Lógica (ALU): La ALU es quien se encarga de realizar cálculos matemáticos y lógicos como sumas, restas, multiplicaciones, divisiones, comparaciones, AND, OR y NOT.
-
Unidad de Control: Es la responsable de la gestión de los procesos en la computadora. Controla el flujo de información, dirige la ejecución de las instrucciones de las demás unidades y gestiona los accesos a la memoria del sistema.
-
FPU (Floating Point Unit): Es una unidad de ejecución especializada en el cálculo de números con punto flotante, lo que la hace adecuada para aplicaciones científicas y de ingeniería.
-
SIMD (Single Instruction, Multiple Data): Es una unidad de ejecución que permite realizar la misma operación en múltiples datos de una sola vez, lo que la hace adecuada para aplicaciones gráficas y de procesamiento de imágenes.
Tipos de registros de una computadora
-
Registro de Programa Contador: Este registro se encarga de almacenar la dirección de la siguiente instrucción a ejecutar.
-
Registro de operando: Tal y como su nombre lo indica, este registro almacena los datos y operandos que se utilizan en las operaciones matemáticas y lógica.
-
Registro de Acumulador: Este registro es el responsable de almacenar el resultado de una operación matemática.
-
Registro de Instrucción: Este registro almacena la instrucción que se está ejecutando en un momento dado contrario al registro de programa contador que almacena la próxima en ser ejecutada.
-
Registro de control: Almacena información sobre el estado del procesador y se utilizan para controlar el flujo de datos y la ejecución de instrucciones.
-
Registro de Propósito General: Estos registros se utilizan para almacenar valores intermedios durante el procesamiento de una instrucción y pueden ser usados para diferentes propósitos.
-
Registro de Estado: Almacena información sobre el estado de la CPU, como la dirección de la última instrucción ejecutada, el resultado de una operación, etc.
-
Registro de banderas: Es un registro especial que contiene un conjunto de bits que representan diferentes estados o banderas. Cada bandera representa un estado diferente y se usa para controlar el flujo de ejecución de las instrucciones. Algunos de los estados que pueden ser representados por las banderas incluyen el estado de resultado de una operación aritmética, el estado de desbordamiento, el estado de igualdad, etc. Estas banderas son usadas por la unidad de control para tomar decisiones sobre el flujo de ejecución.
-
Registros de segmento: Almacenan información sobre la memoria y se utilizan para dividir la memoria en segmentos y proteger los datos y las instrucciones de un programa de otras partes de la memoria.
-
Registros de segmento de pila: Almacenan información sobre la pila, que es una estructura de datos que se utiliza para almacenar y acceder a los valores que se utilizan en la ejecución de un programa.
-
Registro de interrupción: Es un registro especial en un procesador que almacena la dirección de una rutina de interrupción. Es usado por la unidad de control para determinar dónde saltar cuando se produce una interrupción, para poder ejecutar la rutina correspondiente. Esta rutina puede ser llamada por el hardware o el software para manejar eventos específicos, como entrada de datos, errores de sistema, o eventos de tiempo. El registro de interrupción es un componente clave en la gestión de interrupciones en un sistema informático.
Tipos de buses de datos
-
Bus de Datos: Se utiliza para transferir datos entre la memoria y el procesador.
-
Bus de Direcciones: Se utiliza para transferir la dirección de la memoria donde se encuentran los datos que se están solicitando entre el procesador y la memoria.
-
Bus de Control: Se utiliza para transferir información de control como señales de lectura y escritura, entre el procesador y los demás componentes de la computadora.
-
Bus PCI: Se utiliza para conectar dispositivos externos a la computadora como tarjetas de video, tarjetas de sonido, etc.
-
Bus USB: Este bus se utiliza para conectar dispositivos externos a la computadora, como teclados, ratones, dispositivos de almacenamiento y otros dispositivos
1.3 - Memoria RAM
La memoria RAM (Random Access Memory), también conocida como memoria de acceso aleatorio, es un tipo de memoria de acceso aleatorio que se utiliza en computadoras para almacenar datos y programas en uso. Con ser de acceso aleatorio se refiere a al tipo de almacenamiento de datos que permite que se pueda acceder a los datos almacenados en cualquier orden y no en secuencia como los discos, cintas magnéticas, etc.
Se caracteriza por ser una memoria volátil lo que significa que sus contenidos se eliminan cuando se apaga la computadora. La RAM destaca entre las demás formas de memora por ser más rápida, permitiendo de esta forma acceder rápidamente a los datos y programas.
Tipos de memoria RAM
-
SRAM: Acrónimo de Static Random Access Memory (Memoria Estática de Acceso Aleatorio), designa un tipo de memoria que se sustenta en semiconductores y capaz de mantener los datos sin necesidad de circuitos de refrescamiento, siempre y cuando se mantenga alimentada. De este tipo son las memorias NVRAM (Non-volatile Random Access Memory, o RAM no volátil) y MRAM (Magnetoresistive Random Access Memory, o RAM magnética).
-
DRAM: Acrónimo de Dynamic Random Access Memory (Memoria Dinámica de Acceso Aleatorio), basa su tecnología en condensadores, que al perder carga progresivamente, requieren de un circuido de refresco que revisa su carga y la repone. Fue inventada a finales de 1960 y es el tipo más empleado actualmente, pues permite crear módulos de enorme densidad de posiciones y alta velocidad de recuperación. De este tipo son las memorias DRAM Asincrónica y SDRAM (Synchronous Dynamic Random Access Memory, o DRAM sincrónica).
-
SDRAM: Synchronous Dynamic RAM (Memoria Sincrónica Dinámica de Acceso Aleatorio), se trata de un modelo más desarrollado que la tradicional DRAM. Su principal novedad es que incluye un reloj interno que permite realizar órdenes de lectura sin haber terminado de procesar una de escritura. De esta forma, se pueden ejecutar varias órdenes de forma simultánea. Se llevan comercializando desde 1993.
-
DDR SDRAM Double Data Rate Synchronous RAM, Son las memorias que se utilizan en la actualidad. A pesar de que hay varias versiones en función de sus velocidades, todas son del mismo tipo, síncrono.
Su principal característica es que permiten la transferencia de información mediante dos canales distintos de forma simultánea en un mismo ciclo de reloj, por ello reciben el nombre de Double Data (DD).
Entre las características principales de este modelo destaca también que son capaces de transferir 2 bits por cada ciclo de reloj y unas frecuencias de reloj internas de entre 100 y 200 MHz.
-
DDR2 SDRAM: Este modelo es capaz de transferir el doble de bits por cada ciclo de reloj, de 2 a 4 y una frecuencia de reloj interna de 100 a 300 MHz. Es una version mejorada de la DDR SDRAM.
-
DDR3 SDRAM: En este modelo se aumenta la eficiencia energética del componente, con un voltaje de 1,5 frente al 1,8 de la DDR2 y 2,5 de la DDR. Además de esto, su frecuencia de reloj puede ir desde los 100 hasta los 350 MHz. Es una versión mejorada de la DDR2 SDRAM.
-
DDR4 SDRAM: Este modelo mejora aún más la eficiencia energética, reduciendo a 1,3 voltios su consumo. Además, incrementan la frecuencia de reloj desde los 200 hasta los 533 MHz. Es la memoria RAM más utilizada para computadoras comerciales.
-
DDR5 SDRAM: DDR5 es la quinta generación de memoria de acceso aleatorio dinámico síncrono de velocidad de datos doble, también conocida como DDR5 SDRAM. La DDR5 está diseñada con nuevas características para un mayor rendimiento, menor consumo de energía y una integridad de datos más sólida para la próxima década de informática. DDR5 debutó en 2021. DDR5 debuta a 4800MT/s*, mientras que la DDR4 alcanza un máximo de 3200MT/s, un aumento del 50% en el ancho de banda. De acuerdo con los lanzamientos de la plataforma informática, DDR5 ha planificado aumentos de rendimiento que se escalarán a 6400MT/s.
-
LPDDR5: LPDDR5 es la próxima generación de DRAM, que significa Low Power Double Data Rate Type 5. LPDDR5 es el sucesor de LPDDR4X y podrá proporcionar más datos a dispositivos con menor potencia. Se utiliza en muchos dispositivos electrónicos y en teléfonos inteligentes. LPDDR5 fue diseñado para optimizar la eficiencia, el consumo de energía y el rendimiento. La principal ventaja de esta nueva tecnología es que admite velocidades de datos de hasta 4266 MT/s.
1.4 - El concepto de interrupciones
Una interrupción es una situación especial que suspende la ejecución de un programa de modo que el sistema pueda realizar una acción para tratarla. Tal situación se da, por ejemplo, cuando un periférico requiere la atención del procesador para realizar una operación de E/S.
Las interrupciones constituyen quizá el mecanismo más importante para la conexión del microcontrolador con el mundo exterior, sincronizando la ejecución de programas con acontecimientos externos.
Tipos de interrupciones
-
Interrupciones de hardware: Estas son asíncronas a la ejecución del procesador, es decir, se pueden producir en cualquier momento independientemente de lo que esté haciendo el CPU en ese momento. Son las generadas por dispositivos externos a la CPU, como por ejemplo un teclado, un mouse, un disco duro, etc.
-
Interrupciones de software: Son aquellas generadas por un programa en ejecución, como una excepción, una llamada a sistema, una interrupción programada, etc. Para generarlas, existen distintas instrucciones en el código máquina que permiten al programador producir una interrupción.
-
Interrupciones de nivel alto: Son aquellas con alta prioridad y se manejan de forma inmediata por la CPU.
-
Interrupciones de nivel bajo: Son aquellas con baja prioridad y se manejan en el orden en que se reciben.
-
Interrupciones de servicio: Son aquellas que proporcionan un servicio específico a la CPU, como la gestión del reloj o la entrada/salida de datos.
-
Interrupciones de tiempo: Son generadas por un reloj interno a la CPU para indicar que ha transcurrido un tiempo específico.
Sistemas de prioridad
El sistema operativo necesita un mecanismo para priorizar las interrupciones y tratar primero las más urgentes. Para ello, existen varias alternativas:
-
Interrupciones simultáneas: No tienen por qué ocurrir de manera simultánea, sino que se refiere a que en un momento dado puede haber varias interrupciones activas.
-
Interrupciones anidadas: Mientras se está procesando una determinada rutina de servicio de interrupción sucede otra señal de interrupción.
-
Inhibición de interrupciones: Se deshabilitan las demás interrupciones mientras se está tratando una.
Determinación de la fuente que genera la interrupción.
Hay distintas formas de identificar la fuente de una determinada interrupción.
-
Polling: el microprocesador comprueba de manera sistemática todos los dispositivos de manera que «busca» cuál de ellos fue el que solicitó la interrupción.
-
Interrupciones vectorizadas: Como ventajas podemos destacar que suele ser rápido, pero implica un alto costo en el hardware.
-
Hardware paralelo: se utiliza un registro de interrupción cuyos bits se controlan de forma independiente por las señales de petición de interrupción de cada periférico. Según la posición de cada bit en el registro, se establece la prioridad.
Ejemplos de interrupciones
- int 01h-->un solo paso
- int 02h-->interrupción no enmascarable
- int 03h--> punto de interrupcion
- int 04h-->desbordamiento
- int 05h-->impresion de pantalla
- int 08h-->Cronometro
- int 15h-->Servicios del sistema
- int 16h-->Funciones de entrada del teclado
- int 18h-->Entrada con el Basic de Rom
- int 19h-->Cargador ed arranque
- int 1Ah-->Leer y establecer la hora
- int 1Bh-->Obtener el control con una interrupción de teclado.
- int 2oh-->Terminar un programa
- int 33h->Funciones del ratón
1.5 - Llamadas a servicios del sistema.
Es el mecanismo usado por una aplicación para solicitar un servicio al sistema operativo. Las llamadas al sistema comúnmente usan una instrucción especial de la CPU que causa que el procesador transfiera el control a un código privilegiado. previamente especificado por el mismo código. Esto permite al código privilegiado especificar donde va a ser conectado así como el estado del procesador.
Cuando una llamada al sistema es invocada, la ejecución del programa que invoca es interrumpida y sus datos son guardados, normalmente en su PCB (Bloque de Control de Proceso del inglés Process Control Block), para poder continuar ejecutándose luego. El procesador entonces comienza a ejecutar las instrucciones de código de alto nivel de privilegio, para realizar la tarea requerida. Cuando esta finaliza, se retorna al proceso original, y continúa su ejecución. El retorno al proceso demandante no obligatoriamente es inmediato, depende del tiempo de ejecución de la llamada al sistema y del algoritmo de planificación de CPU.
Llamadas al sistema no bloqueantes
Son aquellas llamadas en las que, si lo que se solicita no está disponible, el proceso no se queda bloqueado, sino que devuelven un valor especial indicando la condición de información no disponible.
Llamadas al sistema bloqueantes
La aplicación se bloquea a la espera del resultado. Si un hilo hace una llamada bloqueante, todos los hilos se bloquearán. Si hace una llamada no bloqueante, los demás hilos podrán seguir ejecutando.
Una llamada al sistema es un método o función que puede invocar un proceso para solicitar un cierto servicio al sistema operativo. Dado que los accesos a ciertos recursos del sistema requieren la ejecución de código en modo privilegiado, el sistema operativo ofrece un conjunto de métodos o funciones que el programa puede emplear para acceder a dichos recursos.
Tipos de llamadas al sistema
Control de procesos
- terminar (end), abortar (abort).
- cargar (load), ejecutar (execute).
- crear procesos (create process o submit job), terminar procesos (terminate process).
- fork: inicia un nuevo proceso.
- exec: el programa se ejecuta.
- obtener atributos del proceso (get process attributes), definir atributos del proceso (set process attributes).
Administración de archivos
- crear archivos (create), borrar archivos (delete).
- abrir (open), cerrar (close).
- leer (read), escribir (write), reposicionar (reposition).
- obtener atributos del archivo, definir atributos del archivo.
Administración de dispositivos
- solicitar dispositivo (request), liberar dispositivo (release)
- leer (read), escribir (write), reposicionar (reposition)
- obtener atributos de dispositivo, definir atributos de dispositivo
- conectar y desconectar dispositivos lógicamente.
Mantenimiento de la información
- obtener la hora (time) o la fecha (date), definir la hora o la fecha
- obtener datos del sistema, establecer datos del sistema
- obtener los atributos de procesos, archivos o dispositivos
- establecer los atributos de procesos, archivos o dispositivos
Comunicaciones
- crear, eliminar conexiones de comunicación
- enviar, recibir mensajes
- transferir información de estado
1.6 - Modos de direccionamiento.
Los modos de direccionamiento asignan memoria RAM en porciones que pueden ser referenciadas individualmente para que la unidad central de procesamiento, o CPU, pueda determinar qué ubicación de memoria está siendo utilizada por una instrucción de la máquina. Se les llama modos de direccionamiento a las distintas formas de combinar los operandos según el acceso que se hace a memoria. Existen varios modos de direccionamiento en un procesador, cada uno de ellos tiene características distintas y es usado en diferentes situaciones.
Direccionamiento implícito
- Depende solamente de la instrucción, es decir, la instrucción no lleva parámetros.
- Particularmente en instrucciones que no accesan memoria, o bien que tienen una forma específica de accesarla.
- Ejemplos: PUSHF, POPF, NOP.
Modo registro
- Usa solamente registros como operandos
- Es el más rápido, pues minimiza los recursos necesarios (toda la información fluye dentro del EU del CPU)
- Ejemplo: MOV AX, BX.
Modo inmediato
- Tiene dos operandos: un registro y una constante que se usa por su valor.
- El valor constante no se tiene que buscar en memoria, pues ya se obtuvo al hacer el “fetch” de la instrucción.
- Ejemplo: MOV AH, 9
Modo directo
- Uno de los operandos involucra una localidad específica de memoria
- El valor constante se tiene que buscar en memoria, en la localidad especificada.
- Es más lento que los anteriores, pero es el más rápido para ir a memoria, pues ya “sabe” la localidad, la toma de la instrucción y no la tiene que calcular.
- Ejemplo: MOV AH, [0000]
Modo indirecto
- Se usan los registros SI, DI como apuntadores.
- El operando indica una localidad de memoria, cuya dirección (sólo la parte desplazamiento) está en SI o DI.
- Es más lento que los anteriores, pues tiene que “calcular” la localidad.
- Ejemplos: MOV AL, [SI]
Modo indexado de base
Formato: [ BX o BP + SI o DI (opcionales) + constante (opcional) ] BX o BP indica una localidad base de la memoria
- A partir de BX o BP, se puede tener un desplazamiento variable y uno constante
- La diferencia es el segmento sobre el que trabajan por defecto:
- BX por defecto en el segmento de datos
- BP por defecto en el segmento de pila.
Ejemplos:
- MOV AX, [BX]
- MOV DX, [BX+2]
- MOV CX, [BX+DI]
- MOV DL, [BX+SI+3]
Absoluto
El campo de operando contiene una dirección en memoria, en la que se encuentra la instrucción. Y no se cancela.
Indirecto recursivo
Unos pocos sistemas como el PDP-6 o el PDP-10 tenían la posibilidad de direccionamiento indirecto recursivo. Tal dirección de memoria indirecta tenía un campo de registro para indexación y posiblemente un otro bit indirecto, de modo que el proceso de direccionamiento indirecto con indexación podría teóricamente repetirse cualquier número de veces hasta que se encontrara una dirección sin un bit indirecto en la cadena.
Indirecto mediante registros
El campo de operando de la instrucción contiene un identificador de registro en el que se encuentra la dirección efectiva del operando. El control localiza la instrucción de la memoria y utiliza su parte de dirección para acceder a la memoria de nuevo para leer una dirección efectiva. Unos pocos modos de direccionamiento requieren que el campo de dirección de la instrucción sea sumado al control de un registro especificado en el procesador. La dirección efectiva en este modo se obtiene del siguiente cálculo: Dir. efectiva = Dir. de la parte de la instrucción + Contenido del registro del procesador.
De desplazamiento
Combina el modo directo e indirecto mediante registros.
De pila
Se utiliza cuando el operando está en memoria y en la cabecera de la pila. Este direccionamiento se basa en las estructuras denominadas Pila (tipo LIFO), las cuales están marcados por el fondo de la pila y el puntero de pila (*SP). El puntero de pila apunta a la última posición ocupada. Así, como puntero de direccionamiento usaremos el SP. El desplazamiento más el valor del SP nos dará la dirección del objeto al que queramos hacer referencia. En ocasiones, si no existe C. de desplazamiento solo se trabajará con la cima de la pila.
1.7 - Proceso de ensamblado y ligado.
El proceso de ensamblado y ligado consiste en dos etapas principales en la creación de un programa ejecutable a partir del código fuente escrito en lenguaje de bajo nivel, como el ensamblador.
-
- El programa utiliza un editor de texto para crear un archivo de texto ASCII, conocido como archivo de código fuente.
-
- El ensamblador lee el archivo de código fuete y produce un archivo de código objeto, una traducción del programa a lenguaje máquina. De manera opcional, produce un archivo de listado. Si ocurre un error, el programador debe regresar al paso 1 y corregir el programa.
-
- El enlazador lee el archivo de código objeto y verifica si el programa contiene alguna llamada a los procedimientos en una biblioteca de enlace.
-
- La herramienta cargadora del sistema operativo lee el archivo ejecutable y lo carga en memoria, y bifurca la CPU hacia la dirección inicial del programa, para que éste empiece a ejecutarse.
-
Edición: Los archivos fuente de código ensamblador deben estar en formato ASCII standard. Para esto puede usarse cualquier editor que permita crear archivos sin formato.
-
Ensamblado: El ensamblado se lleva a cabo invocando al MASM. Este puede ser invocado, usando una línea de comando, de la siguiente manera: MASM archivo [,[objeto][,[listado][,[cross]]]]][opciones][;]
Dónde: Objeto.- Es el nombre para el archivo objeto.
Listado. - Nombre del archivo de listado de ensamblado.
cross. Es un archivo de referencias cruzadas.
Objeto. - Es el nombre para el archivo .OBJ Ejecutable. - Nombre del archivo .EXE Mapa. - Nombre del archivo mapa Librería. - Nombre del archivo biblioteca de rutinas
-
Ejecución: Para la ejecución del programa simplemente basta teclear su nombre en el prompt de MS-DOS y teclear ENTER. Con esto el programa será cargado en memoria y el sistema procederá a ejecutarlo.
-
Ligado: el código objeto generado en la etapa de ensamblado se combina con otros archivos objeto y bibliotecas para crear un programa ejecutable completo. El ligador resuelve las referencias externas, como las llamadas a funciones de bibliotecas, y las reemplaza con los valores correctos. También agrupa los archivos objeto en secciones y asigna direcciones a cada una para crear un archivo ejecutable completo
Tipos de ensambladores
-
Ensamblador de bajo nivel: : Este tipo de ensamblador trabaja directamente con el código máquina y es más rápido y eficiente en términos de recursos que los ensambladores de alto nivel. Sin embargo, requieren más conocimiento y habilidades técnicas para utilizarlos.
-
**Ensamblador de nivel medio: Es un tipo de ensamblador que utiliza una sintaxis más cercana al lenguaje de programación de alto nivel. Este tipo de ensamblador permite al programador escribir código en una sintaxis más fácil de leer y entender, sin embargo, los programas generados por el ensamblador de nivel medio aún deben ser traducidos a una representación binaria antes de ser ejecutados por la CPU.
-
Ensamblador de alto nivel: Este tipo de ensamblador proporciona una sintaxis más fácil de leer y escribir que los ensambladores de bajo nivel, lo que los hace más accesibles para programadores que no tienen un conocimiento profundo de la arquitectura de la computadora. Sin embargo, estos ensambladores suelen ser más lentos y requieren más recursos que los ensambladores de bajo nivel.
-
Ensamblador Cruzado: El primer tipo de ensamblador permite el soporte de medios físicos tales como periféricos de entrada y salida. Es utilizado principalmente en el desarrollo de programación para sistemas específicos.
-
Ensamblador Residente: Este tipo de ensambladores permanecen en la memoria de la computadora, y solamente se cargan para permitir la ejecución del programa objeto producido. Este tipo de ensamblador es el más usado para la ingeniería de sistemas de control más pequeños.
-
Macroensambladores: Este tipo específico de ensamblador permite el uso de macroinstrucciones. Son aplicaciones, muchas veces de gran tamaño, que tienen la particularidad de no permanecer en memoria una vez que se ha terminado de generar el código objeto.
-
Microensambladores: Este tipo de ensambladores le proporciona al interprete instrucciones precisas de cómo debe llevar a cabo la CPU una determinada tarea.
-
Ensambladores de una fase: Los ensambladores de una fase tienen la particularidad de leer una línea de programa fuente, traducirla directamente y producir una instrucción en lenguaje máquina por vez. Este tipo de ensambladores son sencillos de utilizar, y además brindan como beneficio ocupar poco espacio en memoria.
-
Ensambladores de dos fases: Es el tipo de ensamblador más usado en la actualidad. Su nombre se debe a que todo el proceso de traducción y ejecución se lleva a cabo en dos etapas. En la primera de ellas el ensamblador analiza el código fuente y lo construyen en una tabla de símbolos. En la segunda etapa, se vuelve a analizar el código fuente del programa ya para traducirlo.
Tipos de ligado:
-
Ligadores estáticos: Son aquellos que crean un archivo ejecutable independiente que contiene todas las secciones necesarias y los recursos necesarios para su ejecución. Este archivo ejecutable puede ser ejecutado en cualquier sistema que cumpla con los requisitos necesarios, sin la necesidad de ningún otro archivo o biblioteca. Un ejemplo de ligador estático es el comando "ld" en Linux.
-
Ligadores dinámicos: Son aquellos que crean un archivo ejecutable que depende de bibliotecas externas para su ejecución. El archivo ejecutable contiene las direcciones de las bibliotecas requeridas, pero no las incluye directamente. Al momento de la ejecución, el sistema operativo busca y carga las bibliotecas necesarias antes de ejecutar el archivo ejecutable. Un ejemplo de ligador dinámico es el "dynamic linker" en Linux y el "loader" en Windows.
1.8 - Desplegado de mensajes en el monitor
Todos los gráficos y el texto que se muestran en el monitor se escriben en la RAM de visualización de vídeo, para después enviarlos al monitor mediante el controlador de vídeo. El controlador de vídeo es en sí un microprocesador de propósito especial, que libera a la CPU principal del trabajo de controlar el hardware de vídeo. Un monitor de pantalla de cristal líquido (LCD) digital directo recibe un flujo de bits digitales directamente desde el controlador de vídeo, y no requiere del barrido de trama.
En este momento, podemos comenzar a escribir las verdaderas instrucciones que le indicarán a la computadora que mensaje y como lo va a desplegar. Iniciaremos primeramente por borrar la pantalla. Esto se puede realizar de muy diversas formas, aquí lo haremos usando el BIOS, el cual es un microchip que se encuentra dentro de toda PC y controla las funciones básicas de entrada y salida (Basic Input Output System).
Lo que haremos es decirle al chip "¡Hey! dime en qué modo está trabajando la tarjeta de video", cuando obtengamos la respuesta le diremos: "Dile a la tarjeta de video que deje de trabajar en ese modo y que comience a trabajar en el modo de video que me diste".
Una instrucción rara, pues lo que le estamos ordenando es que deje de trabajar en el modo en el que está trabajando !y que comience a trabajar en ese mismo modo! Así se lo decimos en su propio lenguaje: principio: mov ah, 0fh int 10h mov ah, 0 int 10h .
Lo primero que vemos es una "etiqueta", con ella le damos nombre a un punto dentro del código, si más tarde dentro del programa deseamos repetir esta parte del código solo tenemos que decir "salta a 'principio'" y ya está.
El primer grupo de instrucciones después de la etiqueta le dicen al BIOS que obtenga la modalidad en la que está trabajando el video. Aquí vemos por primera vez una interrupción (int 10h). Las interrupciones son funciones ya incorporadas dentro del BIOS y del sistema operativo MS-DOS que realizan tareas comunes como leer del disco, mostrar un mensaje en el monitor, o ¡borrar la pantalla!. Enseguida, mediante una función de la interrupción 10h, le decimos que cambie a la misma modalidad de video. Bueno, ahora que la pantalla está limpia, podemos mostrar nuestro mensaje en el monitor. Aquí está el código: lea dx, mensaje_a_mostrar mov ah, 9h int 21h Con la primera instrucción le decimos al procesador "Carga en el registro DX, la dirección de memoria de la variable llamada 'mensaje_a_mostrar'".
Enseguida le decimos que la despliegue en pantalla con la función 9h de la interrupción 21h. Nuestra tarea está terminada, así que digamosle a la computadora que no hay más instrucciones que procesar. int 20h Las instrucciones están terminadas, pero todavía tenemos que decirle a la computadora que valor va a tener la variable 'mensaje_a_mostrar'. mensaje_a_mostrar db "¡Hola Mundo!$",0 El signo de pesos al final de la cadena, es necesario para que el sistema operativo sepa en donde se acaba la cadena (una cadena es un grupo de caracteres) que va a desplegar.
Una vez que terminamos con las instrucciones y valores para la máquina, hay que marcar el archivo para que el compilador sepa que ya terminamos de darle instrucciones a la máquina. CODE ENDS end principio ¡Al fin! ¡Llegamos al final! Aquí está el código fuente completo:
CODE SEGMENT
ASSUME CS:CODE, DS:CODE, SS:CODE, ES:CODE
ORG 100h
principio:
mov ah, 0Fh
rar db
"¡Hola Mundo!$",0
CODE ENDS
end principio
NASM Assembler
NASM es un acrónimo de Netwide Assembler, es un ensamblador libre y de código abierto utilizado para crear programas en lenguaje ensamblador en sistemas operativos como Linux y Windows. NASM es compatible con una amplia gama de arquitecturas de CPU, incluyendo x86, x86-64 y ARM, y ofrece una amplia gama de características, como la resolución de enlaces y la generación de código binario portable.
El NASM fue escrito originalmente por Simón Tatham con ayuda de Julián Hall, y actualmente es desarrollado por un pequeño equipo en GitHub que le hace mantenimiento. Fue lanzado originalmente bajo su propia licencia, pero más adelante fue cambiada por la licencia GNU Lesser General Public License, seguido de un número de problemas políticos causado por la selección de la licencia. Por lo que finalmente fue cambiada por la Licencia BSD simplificada.
Características
- Puede generar varios formatos binarios en cualquier máquina, incluyendo COFF (y el ligeramente diferente formato Portable Executable usado por Microsoft Windows), el a.out, ELF, Mach-O, y el formato binario nativo Minix.
- El NASM define su propio formato binario, RDOFF, que es usado actualmente solamente por el proyecto del sistema operativo RadiOS.
- La variedad de formatos de la salida permite a uno portar los programas a virtualmente cualquier sistema operativo x86.
- Puede crear archivos binarios planos, usables para escribir Gestores de arranque, imágenes ROM, y varias facetas del desarrollo sistemas operativos.
- Puede correr en plataformas diferentes del x86, como SPARC y PowerPC, aunque no puede producir programas usables por esas máquinas.
- Usa la tradicional sintaxis de Intel para el lenguaje ensamblador x86, mientras que otros ensambladores libres, como el ensamblador del GNU (GAS), utilizan la sintaxis de AT&T.
- Evita características como la generación automática de sobreescritura (override) de segmentos y la relacionada directiva ASSUME usada por el MASM y los ensambladores compatibles, pues estas pueden ser a menudo confusas.
Componentes de un programa hecho en NASM
-
Sección de definición de sección: En esta sección se definen las secciones de memoria en las que se guardarán los datos y código. Sección de directivas: En esta sección se establecen las directivas que el ensamblador utilizará para el ensamblado.
-
Sección de datos: En esta sección se declaran las variables y se definen los valores iniciales de las mismas.
-
Sección de código: En esta sección se escriben las instrucciones en lenguaje ensamblador.
-
Sección de etiquetas: En esta sección se pueden definir etiquetas que hacen referencia a direcciones específicas en el código o en los datos.
Por ejemplo:
main
{
int x;
x = 8;
printf x;
}
segment .bss
_x resd 1
segment .text
global main
extern print_int, print_endofline
main:
mov dword [_x], 8
push dword [_x]
call print_int
add esp, 4
call print_endofline
ret
Práctica No. 1 CONFIGURACIÓN DEL ENTORNO DE PROGRAMACIÓN
Practica1_Configuración del entorno.pdf
RESUMEN
En esta primera y única práctica de la unidad número uno se realizó la configuración del entorno de programación en Linux. Para ello, se empezó realizando algunas demostraciones de comandos en la terminal de Linux, después se instalaron por medio de la terminal lo necesario para programar en ensamblador y se terminó realizando el clásico “Hola mundo” que todos los programadores hacemos al empezar con cualquier lenguaje de programación.
OBJETIVO
El objetivo de esta práctica es aprender los comandos básicos de la terminal de Linux y configurar nuestro entorno de programación para empezar a codificar en ensamblador.
INTRODUCCIÓN
Esta práctica se realizó para poder tener ya listo nuestro entorno de programación y comenzar a programar en ensamblador. Adicionalmente, durante el proceso de esta práctica se aprendieron algunos de los comandos básicos para manejar la terminal de Linux y poder correr nuestros programas.
METODOLOGÍA
Ya teniendo Linux instalado en la partición hecha en nuestro disco duro e iniciado sesión en el mismo, vamos a acceder a la terminal de Linux buscándola en el menú de aplicaciones. Estando en la terminal tecleamos “sudo apt install nasm” para instalar el ensamblador a utilizar e introducimos nuestra clave de usuario para conceder los permisos de superusuario tal y como se aprecia en la siguiente imagen.
Una vez que ha terminado la instalación, procedemos a teclear “sudo apt install neovim” para instalar Neovim, un editor de texto basado en Vim. Nuevamente tecleamos nuestra clave de usuario y esperamos a que se complete la instalación.
Ahora tecleamos “sudo apt install build-essential”, referencias para todos los paquetes necesarios para compilar un paquete Debian. Esta vez como se puede apreciar no nos pidió contraseña.
Por último pero no menos importante, instalamos Visual Studio Code, para su instalación se tenían dos opciones: por medio de comandos en la terminal o descargando el ejecutable para Linux directamente de su sitio web. En este caso se optó por descargar el ejecutable del siguiente enlace: Download Visual Studio Code - Mac, Linux, Windows. Una vez instalado, se descargaron extensiones para poder visualizar referencias de lenguaje ensamblador mientras se programa.
Para comprobar que se han instalado correctamente todos los paquetes, se procedió a realizar un “Hola mundo” en Visual y ejecutarlo en la terminal de Linux. Para ello se creó un archivo y se le agregó la extensión “.asm” y se programó el mensaje a mostrar tal y como se muestra en la siguiente imagen.
RESULTADOS
Una vez que se hizo el programa, accedemos a la terminal de Linux y tecleamos los códigos que se aprecian en imagen. Como resultado obtenemos nuestro mensaje previamente codificado por lo que podemos decir que esta práctica fue un éxito.
ANÁLISIS
La práctica se realizó sin ningún contratiempo y el resultado fue exitoso al lograr obtener el tan preciado mensaje que se deseaba visualizar. CONCLUSIONES Podemos concluir en que Linux es un entorno bastante diferente a Windows, no obstante, con su debida investigación no es del todo difícil comenzar a dominar los comandos básicos de la terminal. Nuevamente, podemos afirmar que la práctica fue un éxito total tanto en instalación como en la ejecución del código. Al completar la práctica se adquirieron conocimientos en el manejo básico de la terminal de Linux, algo de la estructura del lenguaje ensamblador y cómo ejecutar nuestros códigos en la terminal de Linux.
REFERENCIAS
Capdevila, E. (2022, 2 mayo). Pregunta frecuente ¿Qué es Linux Build Essential? FAQs de Tecnología. https://tecnofaq.com/pregunta-frecuente-que-es-linux-build-essential/ ¿Qué es neovim? ¿Cómo es diferente de Vim? ¿Y por qué debería importarme? (s. f.). https://qastack.mx/vi/34/what-is-neovim-how-is-it-different-from-vim-and-why-should-i-care Ruelas, U. (2017, 6 septiembre). 01. NASMx86: aprendiendo NASM for the lulz. https://codingornot.com/01-nasmx86-aprendiendo-nasm-for-the-lulz