Want to create interactive content? It’s easy in Genially!
Lenguaje Ensamblador
Julio Cesar Segundo
Created on March 18, 2025
Start designing with a free template
Discover more than 1500 professional designs like these:
View
Akihabara Agenda
View
Akihabara Content Repository
View
Interactive Scoreboard
View
Correct Concepts
View
Semicircle Mind Map
View
Choice Board Flipcards
View
Team Retrospective
Transcript
Julio Cesar Antonio Segundo =Referencias=
Uso de interrupciones para salida de texto
Importancia del Lenguaje Ensamblador
Lenguaje Ensamblador
Características de los Lenguajes de Bajo Nivel
Definición
Ventajas y Desventajas
Ejemplo de código de salida en ensamblador
Interpretación de resultados en la consola
Lenguajes de Bajo Nivel
Importancia de la Programación en Lenguaje Ensamblador
Tipos de registros
Funciones de los registros
Desplegado de mensajes en el monitor
El procesador y sus registros internos
Herramientas de ensamblado y depuración
Lenguaje Ensamblador
Es un lenguaje de bajo nivel que utiliza mnemónicos para representar las instrucciones de máquina.
Definición
Proceso de ligado y generación de ejecutables
Mapeo de memoria
Proceso de ensamblado y ligado
La memoria principal (RAM)
Fases del ensamblado
Ejemplos de cada modo
Definición
Tipos de interrupciones (hardware y software)
Modos de direccionamiento
El concepto de interrupciones
Relativo y basado en registros
Llamadas a servicios del sistema
Ejemplos
Directo e indirecto
Definición
Ejemplos de llamadas
Mecanismo de manejo de interrupciones
Categorías
Llamadas a servicios del sistema en Windows y Linux
Importancia en la gestión de eventos
Inmediato
Definición
Tipos de llamadas al sistema
Ejemplos
Ejemplo de Interrupción de Hardware Cuando un usuario presiona una tecla en el teclado, el teclado genera una interrupción al procesador para que lea la entrada. El procesador detiene temporalmente la ejecución del programa actual y maneja la interrupción para procesar la tecla presionada. Ejemplo de Interrupción de Software En un programa, si el código intenta realizar una división por cero, el sistema operativo generará una interrupción de software para manejar el error, normalmente proporcionando un mensaje de error o tomando una acción correctiva.
Definición
El procesador (también llamado CPU, Central Processing Unit) es el componente principal de un sistema informático encargado de ejecutar instrucciones y realizar cálculos matemáticos, lógicos y de control. Los registros son pequeños bloques de memoria de alta velocidad ubicados dentro del procesador, utilizados para almacenar datos temporales e intermedios que se utilizan en el proceso de ejecución de instrucciones. Los registros son esenciales para la ejecución eficiente de un programa, ya que permiten al procesador acceder rápidamente a los valores y direcciones necesarias para las operaciones.
Proceso de Ligado y Generación de Ejecutables
2.1. Ligado El ligado es el proceso mediante el cual los diferentes archivos objeto generados en la fase de ensamblado se combinan para formar un único archivo ejecutable. Este proceso resuelve las referencias a símbolos externos y resuelve direcciones de memoria que aún no han sido asignadas. Tareas: - Combina código objeto y bibliotecas externas.
- Resuelve direcciones de memoria y referencias externas (por ejemplo, funciones o variables definidas en otros módulos).
2.2. Generación de Ejecutables Después de la fase de ligado, el resultado es un archivo ejecutable que contiene tanto el código de la aplicación como los datos necesarios para ejecutarlo en la máquina. Tareas: - Generación de archivos ejecutables listos para ser cargados en memoria.
- Preparación para la ejecución del programa.
Ventajas y desventajas del lenguaje ensamblador
Ventajas:- Eficiencia en el rendimiento: El código es más rápido porque está optimizado para la arquitectura del hardware.
- Control total sobre el hardware: Permite manipular directamente los registros y la memoria del procesador.
Desventajas:- Complejidad: El código en ensamblador es más difícil de leer y mantener.
- Dependencia del hardware: El código ensamblador es específico para cada tipo de procesador, lo que lo hace menos portable.
- Mayor tiempo de desarrollo: Requiere más tiempo para escribir y depurar en comparación con lenguajes de alto nivel.
Tipos de registros
Los registros dentro de un procesador pueden clasificarse según su función y propósito. Aquí se mencionan algunos de los tipos de registros más comunes: 2.1 Registros generales- Descripción: Son los registros que el procesador utiliza para almacenar datos temporales o resultados de operaciones.
- Ejemplo:
- AX (en arquitecturas x86): Almacena valores temporales en operaciones de 16 bits.
- BX, CX, DX: Otros registros de propósito general en la arquitectura x86.
2.2 Registros de propósito específico- Descripción: Son registros especializados que realizan funciones específicas dentro del procesador.
- Ejemplo:
- PC (Program Counter): Mantiene la dirección de la próxima instrucción a ejecutar.
- SP (Stack Pointer): Apunta a la ubicación actual de la pila (stack) en memoria.
- IP (Instruction Pointer): Similar al PC, mantiene la dirección de la siguiente instrucción en arquitecturas como x86.
2.3 Registros de estado- Descripción: Los registros de estado contienen información sobre el estado actual del procesador, como el resultado de la última operación.
- Ejemplo:
- Flags: Bits individuales que indican el resultado de una operación, como Zero Flag (ZF), Carry Flag (CF), Overflow Flag (OF), entre otros.
2.4 Registros de control- Descripción: Son utilizados para controlar el flujo de ejecución del procesador, como la habilitación de interrupciones o la configuración de los modos de operación.
- Ejemplo:
- Control Register: Usado para controlar la configuración del procesador, como el modo de operación (modo usuario o modo kernel).
La memoria principal (RAM)
La memoria RAM (Memoria de Acceso Aleatorio) es el área de almacenamiento temporal utilizada por el procesador para ejecutar programas y gestionar datos en tiempo real. Su velocidad y capacidad afectan directamente el rendimiento del sistema. El mapeo de memoria es el proceso mediante el cual el sistema operativo organiza la RAM en diferentes secciones, asignando direcciones específicas a cada proceso. En ensamblador, el acceso eficiente a la RAM es fundamental para optimizar el rendimiento de los programas.
El concepto de interrupciones
Las interrupciones son señales que permiten a la CPU pausar temporalmente la ejecución de un programa para atender eventos urgentes, como la entrada de datos desde un teclado o una petición de hardware. Se dividen en interrupciones de hardware (generadas por dispositivos como el teclado o el disco duro) e interrupciones de software (generadas por el propio código del programa para llamar a funciones del sistema). Su correcta gestión es clave en sistemas operativos y en programación de ensamblador para la ejecución eficiente de tareas concurrentes.
Llamadas a servicios del sistema
Las llamadas a servicios del sistema (syscalls) permiten que los programas interactúen con el sistema operativo para realizar tareas como la gestión de archivos, la comunicación con dispositivos y la asignación de memoria. Estas llamadas varían según el sistema operativo: en Windows se manejan a través de APIs como la WinAPI, mientras que en Linux se utilizan interrupciones como INT 80h o la instrucción syscall. En ensamblador, comprender estas llamadas es esencial para desarrollar programas que interactúen con el sistema sin necesidad de alto nivel.
El procesador y sus registros internos
El procesador (CPU) es la unidad central de procesamiento de un sistema informático. Ejecuta instrucciones y controla el funcionamiento del hardware. Tipos de registros Los registros internos del procesador almacenan datos temporalmente para acelerar el procesamiento. Se clasifican en:
- Registros de propósito general: Almacenan datos temporales (ej., AX, BX en x86).
- Registros de segmento: Manejan direcciones de memoria.
- Registros de puntero e índice: Controlan direcciones en memoria.
- Registros de estado (FLAGS): Guardan información sobre el resultado de operaciones.
- Almacenar datos intermedios durante la ejecución de programas.
- Gestionar la ejecución de instrucciones y flujos de control.
- Optimizar el acceso a memoria, reduciendo la latencia.
Proceso de ensamblado y ligado
El ensamblado y el ligado son etapas clave en la conversión de código ensamblador a código ejecutable. El ensamblado convierte el código fuente en lenguaje máquina mediante un ensamblador, pasando por fases como análisis léxico, sintáctico y generación de código. El ligado combina diferentes módulos de código y bibliotecas para formar un ejecutable final. En esta etapa, se resuelven direcciones de memoria y dependencias externas. Comprender este proceso es fundamental para desarrollar programas ensamblador funcionales.
Definición
Una llamada a servicio del sistema (o llamada al sistema o system call) es una interfaz proporcionada por el sistema operativo para que los programas de usuario puedan solicitar servicios del sistema operativo, como acceso a archivos, creación de procesos, gestión de memoria, control de dispositivos de E/S, y más. Estas llamadas permiten que un programa interactúe con los recursos del sistema sin necesidad de conocer los detalles internos del sistema operativo. Las llamadas al sistema proporcionan una abstracción de las funcionalidades del hardware y el sistema operativo, lo que facilita que los programas trabajen de manera más eficiente y segura.
Llamadas a Servicios del Sistema en Windows y Linux
Las llamadas al sistema tienen una implementación diferente en cada sistema operativo debido a las diferencias en sus arquitecturas y API. A continuación se describen algunas de las diferencias y ejemplos en Windows y Linux. Llamadas al Sistema en Windows - CreateFile(): Permite abrir un archivo, dispositivo, o canal de comunicación.
- ReadFile(): Lee datos de un archivo o dispositivo.
- WriteFile(): Escribe datos en un archivo o dispositivo.
- ExitProcess(): Termina un proceso.
- GetTickCount(): Obtiene el número de milisegundos desde que el sistema arrancó.
- En Windows, las llamadas al sistema suelen estar expuestas a través de la API de Win32 y el sistema operativo maneja la abstracción de las llamadas.
Llamadas al Sistema en Linux - fork(): Crea un nuevo proceso como una copia del proceso padre.
- exec(): Reemplaza el proceso actual con un nuevo proceso.
- read(): Lee datos de un archivo descriptor.
- write(): Escribe datos en un archivo descriptor.
- exit(): Termina un proceso.
- En Linux, las llamadas al sistema se ges
Definición
La memoria principal o RAM (Random Access Memory) es un tipo de memoria volátil que el procesador utiliza para almacenar temporalmente los datos y las instrucciones de los programas en ejecución. A diferencia de los discos duros o SSDs, que son memorias de almacenamiento a largo plazo, la RAM permite un acceso mucho más rápido a los datos, lo que es esencial para el rendimiento del sistema. La RAM se utiliza para almacenar datos que están siendo procesados activamente por la CPU. Cuando apagas el sistema, todos los datos en la RAM se pierden, ya que es volátil, a diferencia de la memoria no volátil como el disco duro.
Definición
Una interrupción es un mecanismo mediante el cual una unidad de hardware o software interrumpe temporalmente el flujo normal de ejecución de un programa para darle prioridad a otro proceso, evento o tarea. Las interrupciones permiten que el procesador responda de manera inmediata a situaciones urgentes sin esperar a que el programa actual termine su ejecución. El propósito de las interrupciones es garantizar que el sistema pueda manejar múltiples tareas de manera eficiente y en tiempo real. Cuando se produce una interrupción, el procesador suspende su actividad actual, guarda el estado de ejecución en una pila (si corresponde) y atiende la interrupción, ejecutando el código asociado con ella.
Importancia de la programación en lenguaje ensamblador
El lenguaje ensamblador es un lenguaje de bajo nivel que permite la programación directa del hardware de un sistema. Aunque es más complejo que los lenguajes de alto nivel, ofrece ventajas como:
- Eficiencia y rendimiento: Permite un control preciso del hardware y optimización del código.
- Comprensión del hardware: Facilita el aprendizaje sobre arquitectura de computadoras.
- Uso en sistemas embebidos y críticos: Es fundamental en controladores, BIOS y sistemas con recursos limitados.
Importancia del lenguaje ensamblador
El lenguaje ensamblador es fundamental para la programación de sistemas embebidos, controladores, software de bajo nivel y sistemas operativos. Además, ayuda a los programadores a comprender cómo interactúan los procesos del software con el hardware. Ejemplo: Sistemas embebidos: Programación de dispositivos con recursos limitados, como microcontroladores. Desarrollo de controladores: Interacción entre el hardware y el software.
Lenguajes de Bajo Nivel
Definición: Son aquellos lenguajes que están más cerca del hardware de la máquina, permitiendo un control más directo sobre los recursos del sistema. Características: No dependen de un compilador complejo. Están más orientados a las instrucciones específicas de la máquina. Proporcionan un control detallado del hardware. Ejemplo: Lenguajes como ensamblador y código máquina (binario).
Herramientas de Ensamblado y Depuración
3.1. Herramientas de Ensamblado Assembleurs (Ensambladores): Son programas que convierten el código fuente en lenguaje ensamblador a código objeto. Ejemplos incluyen: - GAS (GNU Assembler): Un ensamblador popular en sistemas Unix.
- NASM (Netwide Assembler): Usado en sistemas x86 y otros.
- MASM (Microsoft Macro Assembler): Ensamblador específico para plataformas Windows.
3.2. Herramientas de Depuración La depuración es una parte crucial del proceso de desarrollo, ya que permite identificar y corregir errores en el código. - GDB (GNU Debugger): Es una de las herramientas más utilizadas para depurar programas escritos en C, C++, y otros lenguajes de bajo nivel.
- OllyDbg: Un depurador de código binario que se usa principalmente para la depuración de programas de 32 bits.
- WinDbg: Depurador avanzado para aplicaciones Windows.
Mapeo de Memoria
El mapeo de memoria se refiere a la asignación y organización de la memoria dentro del sistema. Este proceso describe cómo las direcciones de memoria se relacionan con las ubicaciones físicas en la RAM, y cómo el sistema operativo y los programas usan esas direcciones para acceder a la memoria. El mapeo de memoria permite que el sistema operativo gestione de manera eficiente la asignación de recursos y la protección de la memoria. 2.1. Tipos de mapeo de memoria Existen varias formas de mapeo de memoria, dependiendo del sistema operativo y la arquitectura del procesador: - Mapeo de memoria lineal: En este mapeo, las direcciones de memoria se asignan de manera continua y secuencial a las ubicaciones físicas de la RAM.
- Segmentación: Consiste en dividir la memoria en segmentos lógicos, donde cada segmento puede tener un tamaño diferente (por ejemplo, código, datos, pila).
- Paginación: La memoria se divide en bloques pequeños de tamaño fijo llamados páginas, y la RAM se divide en bloques físicos llamados marcos de página. El sistema operativo gestiona la asignación de páginas a marcos de manera dinámica.
2.2. Direccionamiento - El direccionamiento de memoria es un proceso crucial para acceder correctamente a los datos. Algunas técnicas de direccionamiento incluyen:
- Direccionamiento directo: La dirección de la memoria está directamente especificada por el programa.
- Direccionamiento indirecto: La dirección de memoria no se especifica directamente, sino que se calcula o se busca en una tabla de direcciones.
- Direccionamiento basado en registros: Usa registros de la CPU para almacenar direcciones de memoria, lo que mejora la velocidad de acceso.
2.3. Memoria virtual La memoria virtual es un sistema que permite que un programa utilice más memoria de la que realmente está disponible en la RAM física. El sistema operativo utiliza una parte del almacenamiento (generalmente el disco duro) para simular memoria adicional, que se combina con la RAM para crear la ilusión de que hay más memoria de la que realmente está presente.
Lenguaje ensamblador
El lenguaje ensamblador es un tipo de lenguaje de bajo nivel que utiliza mnemotécnicos o abreviaciones (instrucciones simbólicas) en lugar de los códigos binarios del lenguaje de máquina. Cada instrucción en ensamblador corresponde directamente a una instrucción de la arquitectura del procesador. Ejemplo: Instrucción de ensamblador: MOV AX, 1 Esta instrucción mueve el valor 1 al registro AX del procesador.
Características de los lenguajes de bajo nivel
- Acceso directo al hardware: Los programadores pueden controlar directamente la memoria y los registros del procesador.
- Mayor velocidad: El código generado en ensamblador es más rápido debido a su proximidad al lenguaje de máquina.
- Dependencia del hardware: Los programas escritos en lenguajes de bajo nivel están muy ligados al tipo específico de hardware.
Funciones de los registros
3.1 Almacenamiento temporal de datos Los registros permiten almacenar valores intermedios o temporales durante el procesamiento de instrucciones. Esto ayuda a que el procesador acceda rápidamente a los valores sin tener que recurrir a la memoria principal, lo que mejora la velocidad de ejecución. 3.2 Optimización de la ejecución Los registros mejoran la eficiencia del procesador al almacenar los resultados de operaciones previas, lo que reduce el tiempo necesario para acceder a la memoria RAM y acelera el proceso de ejecución de instrucciones. 3.3 Control del flujo de instrucciones Registros como el Program Counter (PC) y el Instruction Pointer (IP) son cruciales para seguir el flujo del programa, ya que indican la dirección de la próxima instrucción a ejecutar. El Stack Pointer (SP) controla las llamadas a funciones y el almacenamiento de variables locales en la pila. 3.4 Estado del procesador Los registros de estado (flags) permiten que el procesador mantenga un seguimiento de las condiciones de las operaciones anteriores, como si un número es cero o si ocurrió un desbordamiento (overflow), lo que afecta la ejecución de instrucciones condicionales. 3.5 Configuración y control del procesador Algunos registros son utilizados para configurar el modo de operación del procesador (modo usuario o modo privilegiado), controlar interrupciones y realizar tareas de depuración.
Mecanismo de Manejo de Interrupciones
Recepción de la InterrupciónCuando se produce una interrupción, el procesador detiene la ejecución del proceso actual. El procesador entonces guarda el contexto de ese proceso (es decir, el estado de los registros y el contador de programa) para que pueda reanudarse más tarde.Determinación de PrioridadEl procesador puede tener un sistema de prioridades para manejar múltiples interrupciones. Las interrupciones de mayor prioridad se atienden primero.Servicio de la InterrupciónEl procesador dirige la ejecución al código correspondiente, conocido como manejador de interrupciones, que toma las medidas adecuadas para gestionar la interrupción (por ejemplo, leer datos del teclado, manejar un error de memoria, etc.).Restauración del ContextoDespués de que se atiende la interrupción, el procesador restaura el contexto del proceso original, reanudando la ejecución donde se detuvo antes de la interrupción.Cuando se produce una interrupción, el procesador detiene la ejecución del proceso actual. El procesador entonces guarda el contexto de ese proceso (es decir, el estado de los registros y el contador de programa) para que pueda reanudarse más tarde.Determinación de PrioridadEl procesador puede tener un sistema de prioridades para manejar múltiples interrupciones. Las interrupciones de mayor prioridad se atienden primero.Servicio de la InterrupciónEl procesador dirige la ejecución al código correspondiente, conocido como manejador de interrupciones, que toma las medidas adecuadas para gestionar la interrupción (por ejemplo, leer datos del teclado, manejar un error de memoria, etc.).Restauración del ContextoDespués de que se atiende la interrupción, el procesador restaura el contexto del proceso original, reanudando la ejecución donde se detuvo antes de la interrupción.
Interrupciones
2.1. Interrupciones de Hardware Descripción: Son interrupciones generadas por componentes físicos del sistema, como dispositivos de entrada/salida (teclado, mouse, impresora, etc.) o fallos en el hardware (por ejemplo, un error de memoria). Estas interrupciones son provocadas por la necesidad de interacción con el procesador para manejar eventos externos. Ejemplos de interrupciones de hardware incluyen: - Teclado: Cuando una tecla es presionada, el teclado genera una interrupción para que el procesador lea la entrada.
- Dispositivo de red: Un paquete de datos recibido en una tarjeta de red genera una interrupción para procesar la información.
- Timer: Un temporizador puede generar interrupciones periódicas para controlar el tiempo en sistemas operativos.
2.2. Interrupciones de Software Descripción: Son interrupciones generadas por software, es decir, por el propio código del programa en ejecución. Estas interrupciones ocurren cuando un programa necesita realizar una acción particular que requiere la intervención del sistema operativo o del hardware. Ejemplos de interrupciones de software incluyen: - Llamadas al sistema: Cuando un programa necesita acceso a recursos del sistema operativo, como acceder a archivos o crear procesos.
- Excepciones: Errores como división por cero, acceso a memoria no válida, etc., que causan una interrupción para manejar el error adecuadamente.
Importancia en la Gestión de Eventos
Tiempo Real Las interrupciones permiten que el sistema responda en tiempo real a eventos sin la necesidad de que el procesador espere a que un programa termine de ejecutarse. Esto es crucial en sistemas embebidos y en tiempo real, como los dispositivos de control industrial. Multitarea y Multitarea Cooperativa Mediante el uso de interrupciones, los sistemas operativos pueden administrar múltiples tareas de manera eficiente, interrumpiendo el flujo de un programa y permitiendo que otras tareas se realicen sin interferencias. Manejo de Recursos y Error Las interrupciones permiten una respuesta rápida ante situaciones críticas, como errores de hardware, la necesidad de atención del usuario o el control de dispositivos de E/S.
Modos de direccionamiento
El modo de direccionamiento define cómo un procesador accede a los datos en la memoria. Existen varios tipos, como el modo inmediato (donde el valor está en la instrucción), directo e indirecto (donde se usa una dirección de memoria), y relativo o basado en registros (donde la dirección se calcula en función de un registro). Elegir el modo de direccionamiento adecuado en ensamblador influye en la eficiencia del programa, ya que determina la rapidez con la que se accede a los datos.
Definición
El modo de direccionamiento es el método o técnica que utiliza el lenguaje ensamblador o el procesador para acceder a los operandos (datos) necesarios para ejecutar una instrucción. Este modo determina cómo se localiza la dirección de memoria de los datos requeridos para una operación. Los modos de direccionamiento varían dependiendo del tipo de operación que se quiera realizar y de los registros o memorias involucradas.
Directo e Indirecto
Modo Directo En el modo directo, la instrucción contiene la dirección de memoria donde se encuentra el operando. No hay necesidad de realizar más cálculos para localizar el operando, ya que la dirección está especificada explícitamente. Definición: El operando se encuentra en la memoria en la dirección indicada en la instrucción. Ejemplo: MOV AX, [1000h] ; Carga el valor ubicado en la dirección 0x1000h de la memoria en AX En este caso, se está accediendo directamente a la dirección de memoria 0x1000h. Modo Indirecto En el modo indirecto, la instrucción contiene un registro que guarda la dirección de memoria donde se encuentra el operando. El valor del registro es utilizado como una dirección para acceder a la memoria. Definición: El operando se encuentra en la dirección de memoria contenida en un registro. Ejemplo: MOV AX, [BX] ; Carga el valor ubicado en la dirección de memoria contenida en el registro BX
Categorías de Llamadas a Servicios del Sistema
Llamadas de Gestión de Procesos Estas llamadas están relacionadas con la creación, terminación y control de procesos. Incluyen operaciones como iniciar o terminar un proceso, esperar a que termine un proceso, y más. Ejemplo: fork() en Linux. Llamadas de Gestión de Archivos Permiten a los programas interactuar con el sistema de archivos, abriendo, cerrando, leyendo, escribiendo o eliminando archivos. Ejemplo: open(), read(), write(). Llamadas de Gestión de Memoria Estas llamadas se encargan de la asignación y liberación de memoria, así como de la administración de espacios de memoria dentro de los programas. Ejemplo: malloc() en C. Llamadas de Entrada/Salida (E/S) Permiten el acceso a dispositivos de entrada/salida, como teclados, pantallas, discos y otros dispositivos. Ejemplo: read(), write(), ioctl(). Llamadas de Control de Dispositivos Se utilizan para controlar o interactuar con dispositivos de hardware, como impresoras o tarjetas de red. Ejemplo: ioctl() en Unix/Linux. Llamadas de Comunicación entre Procesos (IPC) Permiten que los procesos se comuniquen entre sí, ya sea mediante señales, pipes, sockets o memoria compartida. Ejemplo: pipe(). Llamadas de Gestión de Señales Se utilizan para manejar señales del sistema, como interrupciones o eventos específicos. Ejemplo: signal() en C.
Tipos de Llamadas al Sistema
Llamadas Síncronas El proceso que realiza la llamada se bloquea hasta que el sistema operativo complete la tarea solicitada, lo que significa que el proceso espera a que termine la ejecución de la llamada antes de continuar. Llamadas Asíncronas El proceso no se bloquea, sino que la llamada es ejecutada en segundo plano, y el proceso puede continuar su ejecución mientras espera la respuesta del sistema operativo.
Ejemplos de Llamadas a Servicios del Sistema en Windows y Linux
-Ejemplo de Llamada al Sistema en Windows Leer un archivo en Windows: HANDLE hFile = CreateFile("archivo.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { // Error al abrir el archivo } DWORD bytesRead; char buffer[100]; if (ReadFile(hFile, buffer, sizeof(buffer), &bytesRead, NULL)) { // Se leyeron los datos correctamente } CloseHandle(hFile); Llamadas al sistema usadas: -Ejemplo de Llamada al Sistema en Linux Leer un archivo en Linux: #include <fcntl.h> #include <unistd.h> int fd = open("archivo.txt", O_RDONLY); if (fd == -1) { // Error al abrir el archivo } char buffer[100]; ssize_t bytesRead = read(fd, buffer, sizeof(buffer)); if (bytesRead > 0) { // Se leyeron los datos correctamente } close(fd);
Ejemplo
- Inmediato,el operando es un valor constante incluido en la instrucción. MOV AX, 5
- Directo, la instrucción especifica directamente la dirección de memoria del operando. MOV AX, [1234h]
- Indirecto. el operando se encuentra en una dirección indicada por un registro. MOV AX, [BX]
- Relativo, la dirección de memoria se calcula sumando un desplazamiento a una dirección base. JMP [BX+4]
- Basado en Registros, la dirección de memoria es proporcionada por uno o más registros. MOV AX, [BX+SI]
Proceso de Ensamblado y Ligado
1.1. Análisis En esta fase, el ensamblador lee el código fuente en lenguaje ensamblador y realiza un análisis léxico y sintáctico. El objetivo principal de esta fase es comprobar la validez del código y traducirlo a una forma que sea comprensible para el proceso de traducción posterior. Tareas: - Verificación de errores de sintaxis.
- Traducción de las instrucciones de ensamblador en instrucciones de máquina (código binario).
1.2. Traducción En la fase de traducción, el código ensamblador se convierte en código objeto. Este código objeto está en un formato binario, pero aún no es un programa ejecutable completo. Esta fase traduce cada instrucción en un conjunto de códigos de operación que el procesador puede entender. Tareas: - Conversión de instrucciones de lenguaje ensamblador a instrucciones de máquina.
- Resolución de etiquetas y direcciones.
1.3. Generación de Código Máquina En esta fase, el código objeto generado en la fase anterior se traduce completamente en código máquina o código binario. Este es el formato que se puede cargar y ejecutar directamente en la CPU. Tareas: - Generación de archivos binarios.
- Preparación de la salida para su posterior vinculación y ejecución
Inmediato
El modo de direccionamiento inmediato es el más simple. En este modo, el valor del operando es proporcionado directamente en la instrucción. No se requiere acceder a la memoria para obtener el dato, ya que el operando es una constante codificada dentro de la instrucción. - Definición: El operando está contenido directamente en la instrucción.
- Ejemplo:
MOV AX, 5 ; Carga el valor 5 directamente en el registro AX
Relativo y Basado en Registros
Modo Relativo El modo relativo utiliza una dirección base que se encuentra almacenada en un registro y le suma un valor desplazado (offset) especificado en la instrucción. La dirección final a la que se accede es la suma de la dirección base y el desplazamiento. Definición: Se utiliza una dirección base contenida en un registro, a la que se le agrega un desplazamiento especificado. Ejemplo: MOV AX, [BX+5] ; Carga el valor ubicado en la dirección de memoria (BX + 5) en AX En este ejemplo, BX es la dirección base, y el desplazamiento 5 se suma a esa dirección base para obtener la dirección final. Modo Basado en Registros El modo basado en registros utiliza directamente un registro para almacenar la dirección de memoria del operando. La diferencia con el modo indirecto es que no se hace un cálculo adicional (como sumar un desplazamiento), sino que simplemente se utiliza el contenido del registro como la dirección de memoria. Definición: El operando se encuentra en la dirección de memoria contenida en un registro, sin desplazamiento adicional. Ejemplo: MOV AX, [BX] ; Carga el valor ubicado en la dirección de memoria contenida en el registro B
Ejemplo de Código de Salida en Ensamblador
section .data
mensaje db "Hola, mundo!", "$" ; Definimos el mensaje con un terminador "$"
section .text
global _start
_start:
mov ah, 09h ; Función 09h de INT 21h (imprimir cadena)
mov dx, mensaje ; Dirección del mensaje
int 21h ; Llamamos a la interrupción DOS
mov ah, 4Ch ; Salida del programa (DOS)
int 21h
Explicación:
- AH = 09h indica que se desea imprimir un mensaje en pantalla.
- DX contiene la dirección del mensaje a mostrar.
- INT 21h ejecuta la función de salida de texto.
- El programa finaliza con AH = 4Ch e INT 21h.
Uso de Interrupciones para Salida de Texto
En ensamblador, el desplegado de mensajes en el monitor se realiza utilizando interrupciones del sistema, que permiten interactuar con la pantalla a nivel de hardware. Estas interrupciones dependen del sistema operativo y del procesador. En sistemas DOS, la interrupción más utilizada es INT 21h, que pertenece a las interrupciones de software del BIOS y del DOS. En sistemas Linux, se emplean llamadas al sistema a través de la interrupción INT 80h o el sistema de llamadas syscall.
Desplegado de mensajes en el monitor
El despliegue de mensajes en ensamblador se realiza mediante interrupciones o llamadas al sistema que envían datos a la salida estándar. En DOS, se usa INT 21h para mostrar texto en pantalla, mientras que en Linux se emplea sys_write mediante syscall. Estos métodos permiten interactuar con el usuario a nivel de bajo nivel, facilitando la depuración y la comunicación en programas ensamblador. Es una de las primeras funcionalidades implementadas al aprender ensamblador, ya que ayuda a visualizar la ejecución del código.