En este tema, aprenderemos sobre subrutinas y procedimientos en el lenguaje ensamblador. Las subrutinas y procedimientos son bloques de código que se pueden llamar desde diferentes partes de un programa, lo que permite la reutilización del código y una mejor organización.
Conceptos Clave
- Subrutina: Un bloque de código que realiza una tarea específica y puede ser llamado desde cualquier parte del programa.
- Procedimiento: Similar a una subrutina, pero generalmente se refiere a un bloque de código que puede recibir parámetros y devolver valores.
- Llamada a subrutina: La instrucción que transfiere el control del programa a la subrutina.
- Retorno de subrutina: La instrucción que devuelve el control del programa al punto desde donde se llamó la subrutina.
Estructura de una Subrutina
Una subrutina en ensamblador generalmente sigue esta estructura:
- Prologo: Código que se ejecuta al inicio de la subrutina para preparar el entorno.
- Cuerpo: El código principal de la subrutina.
- Epilogo: Código que se ejecuta al final de la subrutina para limpiar el entorno y retornar al punto de llamada.
Ejemplo de Subrutina en x86 Assembly
A continuación, se muestra un ejemplo de una subrutina simple en ensamblador x86 que suma dos números:
section .data
num1 db 5
num2 db 10
result db 0
section .text
global _start
_start:
; Llamada a la subrutina sum
call sum
; Salida del programa
mov eax, 1 ; syscall: exit
int 0x80
sum:
; Prologo
push ebp ; Guardar el valor de EBP
mov ebp, esp ; Establecer el nuevo valor de EBP
; Cuerpo
mov al, [num1] ; Cargar num1 en AL
add al, [num2] ; Sumar num2 a AL
mov [result], al ; Guardar el resultado
; Epilogo
mov esp, ebp ; Restaurar el valor de ESP
pop ebp ; Restaurar el valor de EBP
ret ; Retornar al punto de llamadaExplicación del Código
-
Prologo:
push ebp: Guarda el valor del registro EBP en la pila.mov ebp, esp: Establece el nuevo valor de EBP al valor actual de ESP.
-
Cuerpo:
mov al, [num1]: Carga el valor denum1en el registro AL.add al, [num2]: Suma el valor denum2al registro AL.mov [result], al: Guarda el resultado de la suma en la variableresult.
-
Epilogo:
mov esp, ebp: Restaura el valor de ESP al valor que tenía antes de la llamada a la subrutina.pop ebp: Restaura el valor de EBP.ret: Retorna al punto de llamada.
Ejercicio Práctico
Ejercicio 1: Crear una Subrutina para Multiplicar Dos Números
Escribe una subrutina en ensamblador x86 que multiplique dos números y almacene el resultado en una variable.
Solución
section .data
num1 db 4
num2 db 3
result db 0
section .text
global _start
_start:
; Llamada a la subrutina multiply
call multiply
; Salida del programa
mov eax, 1 ; syscall: exit
int 0x80
multiply:
; Prologo
push ebp ; Guardar el valor de EBP
mov ebp, esp ; Establecer el nuevo valor de EBP
; Cuerpo
mov al, [num1] ; Cargar num1 en AL
mov bl, [num2] ; Cargar num2 en BL
mul bl ; Multiplicar AL por BL, resultado en AX
mov [result], al ; Guardar el resultado (parte baja de AX)
; Epilogo
mov esp, ebp ; Restaurar el valor de ESP
pop ebp ; Restaurar el valor de EBP
ret ; Retornar al punto de llamadaExplicación del Código
-
Prologo:
push ebp: Guarda el valor del registro EBP en la pila.mov ebp, esp: Establece el nuevo valor de EBP al valor actual de ESP.
-
Cuerpo:
mov al, [num1]: Carga el valor denum1en el registro AL.mov bl, [num2]: Carga el valor denum2en el registro BL.mul bl: Multiplica el valor de AL por BL, el resultado se almacena en AX.mov [result], al: Guarda el resultado de la multiplicación (parte baja de AX) en la variableresult.
-
Epilogo:
mov esp, ebp: Restaura el valor de ESP al valor que tenía antes de la llamada a la subrutina.pop ebp: Restaura el valor de EBP.ret: Retorna al punto de llamada.
Conclusión
En esta sección, hemos aprendido sobre subrutinas y procedimientos en ensamblador, su estructura y cómo implementarlas. Las subrutinas permiten la reutilización del código y una mejor organización del programa. Hemos visto ejemplos prácticos y realizado un ejercicio para reforzar los conceptos aprendidos. En el siguiente tema, exploraremos las operaciones con la pila, que son fundamentales para el manejo de subrutinas y procedimientos.
Curso de Programación en Ensamblador
Módulo 1: Introducción al Lenguaje Ensamblador
- ¿Qué es el Lenguaje Ensamblador?
- Historia y Evolución del Ensamblador
- Conceptos y Terminología Básica
- Configuración del Entorno de Desarrollo
Módulo 2: Fundamentos del Lenguaje Ensamblador
- Comprendiendo la CPU y la Memoria
- Registros y Sus Funciones
- Sintaxis y Estructura Básica
- Escribiendo Tu Primer Programa en Ensamblador
Módulo 3: Representación de Datos e Instrucciones
- Sistemas Binario y Hexadecimal
- Tipos y Tamaños de Datos
- Instrucciones Aritméticas
- Instrucciones Lógicas
Módulo 4: Flujo de Control
Módulo 5: Conceptos Avanzados de Ensamblador
- Interrupciones y Llamadas al Sistema
- Macros y Ensamblado Condicional
- Ensamblador Inline en Lenguajes de Alto Nivel
- Optimización del Código en Ensamblador
Módulo 6: Ensamblador para Diferentes Arquitecturas
- Lenguaje Ensamblador x86
- Lenguaje Ensamblador ARM
- Lenguaje Ensamblador MIPS
- Lenguaje Ensamblador RISC-V
Módulo 7: Aplicaciones Prácticas y Proyectos
- Escribiendo un Cargador de Arranque Simple
- Creando un Núcleo Básico de Sistema Operativo
- Interfaz con Hardware
- Depuración y Perfilado del Código en Ensamblador
