Bueno supongo que todos saben que la mayoria de los compiladores de C++ permiten incluir instrucciones de ensamblador dentro del codigo fuente y estas son ensambladas directamente en el codigo objeto. A esto se le llama inline assembler generalmente.
Pero eso no es siquiera interesante; lo que si es muy interesante es la capacidad de escribir librerias (estaticas y dinamicas) tanto en ensamblador como en C++ (MASM y VC++) y linkearlas en ambos lenguajes.
Osea, que por ejemplo podemos crear una libreria en ensamblador y linkearla estaticamente en un programa de C++. Vamos a ver el ejemplo.
Codigo de la libreria de ensamblador (en rojo):
.386
.model stdcall,flat
include windows.inc
include kernel32.inc
include user32.inc
includelib kernel32.lib
includelib user32.lib
CTEXT MACRO text:VARARG
LOCAL TxtName
.data
TxtName BYTE text,0
.code
EXITM <OFFSET TxtName>
ENDM
SayLong PROTO number:DWORD
.code
SayLong PROC number:DWORD
LOCAL pointer:DWORD
invoke GetProcessHeap
invoke HeapAlloc,eax,HEAP_ZERO_MEMORY or HEAP_GENERATE_EXCEPTIONS,1024
mov pointer,eax
invoke wsprintf,pointer,CTEXT("%d"),number
invoke MessageBox,0,pointer,pointer,0
invoke GetProcessHeap
invoke HeapFree,eax,0,pointer
ret
SayLong ENDP
End
Tranquilidad que ahora paso a explicar el codigo anterior.
.386 es una directiva que le indica a MASM que nuestro codigo va optimizado para la arquitectura 386
.model stdcall,flat es una directiva que le indica a MASM que nuestro codigo usa stdcall (convencion de funciones que utiliza la API de Windows) y un modelo de memoria plano (el unico posible en Windows).
Los includes justamente incluyen bibliotecas al estilo de los .H de C++, para conseguir estas bibliotecas hay que tener MASM32 MASM32 instalado y con el path configurado.
Los includelib nos ahorran pasarle en la linea de comandos parametros de librerias que vamos a linkear, tambien hay que tener el MASM32 o sino crearlas (eso lo dejamos para otro tutorial).
El macro CTEXT nos permite utilizar texto al modo de C++ usando CTEXT("TEXTO") cosa que no es posible directamente en ensamblador.
La funcion SayLong simplemente muestra un MessageBox con el numero que hayamos especificado como parametro.
Ustedes diran que carajo hacemos con este codigo, bueno aca esta la respuesta, ensamblamos y linkeamos con MASM:
ml /c /Cp /coff asm_called.asm
lib asm_called.obj
Con eso conseguimos el archivo asm_called.obj que es el codigo objeto y el archivo asm_called.lib que es el codigo ejecutable que vamos a linkear desde C++.
Ahora el codigo de C++ que llama a la funcion de ensamblador (en rojo como siempre)
#include <windows.h>
extern "C" void __stdcall SayLong(DWORD number);
void main()
{
SayLong(50);
}
Muy simple este codigo, muy simple. Declara la funcion externa SayLong con el paso de paremetros de stdcall (la misma que usamos en ensamblador). Y la llama desde un main con un parametro de 50.
Compilamos y linkeamos con VC++:
cl -c calling_asm.cpp
link calling_asm.obj asm_called.lib kernel32.lib user32.lib
Ahora obtenemos un archivo objeto calling_asm.obj y un archivo ejecutable calling_asm.exe.
Ejecuten el archivo calling_asm.exe y veran que aparece un MessageBox con el numero 50, la rutina SayLong (programa en ensamblador) fue llamada desde C++.
Espero que les haya gustado el tutorial y hayan aprendido algo nuevo.
Saludos,
Mariano.
Autor: Mariano Ventaja
http://www.c0d3rz.com.arDescarga:
http://www.c0d3rz.com.ar/foro/viewtopic.php?t=14