Assembly y C


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 printfscanfexit 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 printfscanf 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

Posted in

Leave a Reply