El compilador NASM nos permite llamar funciones de C desde el código ensamblador, lo cual hace más fácil el desarrollo de nuestro programa.
En el artículo Programación en Ensamblador muestro un ejemplo sencillo que muestra el clásico Hello Worldutilizando la función printf.
Ahora veamos un ejemplo para utilizar las funciones printf, scanf y exit en ensamblador.
Llamando a C desde Ensamblador
El siguiente ejemplo realizará la operación: 2 * x + 1
SECTION .data Mensaje: db "Numero entero: ", 0 Formato: db "%d", 0 Resultado: db "Resulado: %d", 10, 0 Valor: db 4 * 0 SECTION .text global main extern scanf extern printf extern exit main: push Mensaje call printf add esp, 4 push Valor push Formato call scanf add esp, 8 mov eax, dword [Valor] add eax, eax inc eax push eax push Resultado call printf call exit
$ nasm -f elf Test.S $ gcc -o Test Test.o $ ./Test Numero entero: 4 Resulado: 9
Llamando a Ensamblador desde C
Ahora llamemos una función desarrollada en Ensamblador desde C.
Este ejemplo es bastante sencillo, lo único que hace es sumar los valores de “x” y “y” y después le resta el valor de“z”.
Resultado = X + Y – Z
// Código en C
// Llamamos a la función de ensamblador declarándola de la siguiente manera:
// extern int operacion(int, int, int);
#include <stdio.h>
int main(void)
{
int x = 30;
int y = 90;
int z = 10;
int resultado;
extern int operacion(int, int, int);
resultado = operacion(x, y, z);
printf("Resultado = %dn", resultado);
return 0;
}
; Código en Ensamblador segment .text global operacion operacion: enter 0,0 mov eax, [ebp+8] add eax, [ebp+12] sub eax, [ebp+16] leave ret
Compilamos y ejecutamos nuestro programa: $ nasm -f elf Suma.S $ gcc -o Test Test.c Suma.o $ ./Test Resultado = 110
Ejemplo mixto
El siguiente ejemplo muestra un programa que en el código Ensamblador llama a C y en el código C llama a Ensamblador.
Este programa suma un arreglo de 5 números enteros. Desde el código en C llamamos a la función suma_arregloescrita en Ensamblador y en el mismo código llamamos a las funciones printf y scanf de C.
#include <stdio.h>
#define SIZE 5
int main(void)
{
int value[SIZE];
extern int suma_arreglo(int *, int);
printf("Suma = %dn", suma_arreglo(value, SIZE));
return 0;
}
segment .data scanf_formato db "%d", 0 printf_formato db "Ingresa un arreglo de %d valores:", 10, 13, 0 segment .text global suma_arreglo extern printf extern scanf suma_arreglo: enter 0, 0 mov ecx, [ebp+12] push ecx push dword printf_formato call printf add esp, 8 mov edx, [ebp+8] mov ecx, [ebp+12] leer_valores: push ecx push edx push dword scanf_formato call scanf add esp, 4 pop edx pop ecx add edx, 4 dec ecx jnz leer_valores mov edx, [ebp+8] mov ecx, [ebp+12] sub eax, eax sumar_valores: add eax, [edx] add edx,4 dec ecx jnz sumar_valores leave ret
$ nasm -f elf Suma.S $ gcc -o Test Test.c Suma.o $ ./Test Ingresa un arreglo de 5 valores: 2 6 5 3 4 Suma = 20