miércoles, 1 de abril de 2015

LLamadas a rutinas de asembler desde c++

LLamadas a rutinas de asembler desde c++


A continuacion presentamos un pequeño programa en asembler que es llamado desde C++.

El programa en asembler carga una constante en el registro "RAX", lo llamamos "c.asm".




global GetValueFromASM

segment .data

segment .text
GetValueFromASM:
        mov rax, 8679869
        ret

El programa en "C++" que llama a la funcion "GetValueFromASM"  a este programa la guardamos en el archivo "main.pp".

#include <iostream>
using namespace std;
extern "C" int GetValueFromASM();

int main()
{
cout<<"ASM said " <<GetValueFromASM()<<endl;
return 0;
}
Para facilitar la compilacion realizamos un archivo "makefile" con el siguiente código.


runme: main.cpp c.o
 g++ main.cpp c.o -o runme

c.o: c.asm
 nasm -f elf64 c.asm -o c.o

lo ejecutamos y obtenemos lo siguiente:


dbritos@HP:~/asm$ make
nasm -f elf64 c.asm -o c.o
g++ main.cpp c.o -o runme
dbritos@HP:~/asm$ ./runme
ASM said 8679869
dbritos@HP:~/asm$ 


Pasando variables al asembler.



En la arquitectura "x64" las seis primeras variables enteras "C++" las pasa a través  de registros.
1    RDI
2    RSI
3    RDX
4    RCX
5    R8
6    R9

El asembler le retorna al "C++" las variables a través del registro "RAX"


El programa en "C++" que llama al programa "c" que dentro del programa a la función se le asigna el nombre de "AddInts()" a este programa la guardamos en el archivo "main.pp".


#include <iostream>
using namespace std;
extern "C" int AddInts(int a, int b, int c, int d);
int main()
{
int a,b,c,d;
cout<<"Escriba un numero:";
cin>>a;
cout<<"Escriba el segundo numero:";
cin>>b;
cout<<"Escriba el tercer numero:";
cin>>c;
cout<<"Escriba el cuarto numero:";
cin>>d;
cout<<"La suma de enteros es:"<<AddInts(a,b,c,d)<<endl;
return 0;
}
El programa en asembler que suma las cuatro variables y devuelve la suma en el registro "RAX", lo llamamos "addints.asm".


global AddInts
segment .data
segment .text

AddInts:
        mov eax,edi
        add eax,esi
        add eax,ecx
        add eax,edx
        ret

Para facilitar la compilación realizamos un archivo "makefile" con el siguiente código.

runme: main.cpp addints.o
        g++ main.cpp addints.o -o runme

addints.o: addints.asm
        nasm -f elf64 addints.asm -o addints.o

Lo ejecutamos y obtenemos los siguientes resultados:

/nasm/sumaabcd$ make
g++ main.cpp addints.o -o runme

/nasm/sumaabcd$ ./runme
Escriba un numero:1
Escriba el segundo numero:2
Escriba el tercer numero:3
Escriba el cuarto numero:4
La suma de enteros es:10

Bibliografia


 http://vikaskumar.org/amd64/

No hay comentarios:

Publicar un comentario