hola de nuevo ;D , tengo una funcion en c que lleva un parametros fijo, y luego permite mas parametros que no estan definidos ,
lo que necesito es saber con asm la direccion de esos parametros, pero aqui viene el tema de la convencion de llamada me parece :-\ , yo en este caso quisiera saber la direccion del segundo parametro, porque yo se que se le va a pasar 1 mas, por eso digo el segundo
int AgregarRegistro(int reg_tipo, ...)
{
void* ptrreg;
__asm eax, esp
__asm add eax,4
__asm mov ptrreg, eax
//......
}
supongamos que la llamo asi
class Usuario reg;
AgregarRegistro(1 , reg);
bueno yo necesitaria saber con asm la direccion de reg, esto lo haria dentro de la propia AgregarRegistro()
alguna idea :huh:
PS: noten que puse add 4 porque supuse que el primer parametro fijo ocupa 4 bytes, entonces despues de ese viene el segundo osea el que quiero, pero esto no estoy seguro, por eso pregunto
Hasta donde se, en ASM los params se PUSHean al reves de como los declaras.
int AgregarRegistro(int param1, int param2)
{
void* ptrreg;
void* ptrreg2;
__asm eax, dword ptr [esp+4] //recupera param2
__asm mov ptrreg, eax
__asm eax, dword ptr [esp+8] //recupera param1
__asm mov ptrreg2, eax
}
Si no es asi, debe ser al reves... ;D
Saludos!
Cita de: MCKSys Argentina en 31 Agosto 2011, 18:28 PM
Hasta donde se, en ASM los params se PUSHean al reves de como los declaras.
int AgregarRegistro(int param1, int param2)
{
void* ptrreg;
void* ptrreg2;
__asm eax, dword ptr [esp+4] //recupera param2
__asm mov ptrreg, eax
__asm eax, dword ptr [esp+8] //recupera param1
__asm mov ptrreg2, eax
}
Si no es asi, debe ser al reves... ;D
Saludos!
no sería asi exactamente, fijate:
include 'win32ax.inc'
.data
cadena1 db 'primero',0
cadena2 db 'segundo',0
.code
start:
push cadena2
push cadena1
call Msgbox
invoke MessageBoxA,0,"Sali del proceso",0,0
ret
Msgbox:
pop eax ; dirección de retorno
pop ecx ;primer parametro
pop edx ;segundo parametro
push eax
invoke MessageBoxA,0,edx,ecx,0
pop eax
jmp eax ; retornamos
.end start
Aunque con las macros de las funciones y tal creo qeu variaria un poco.
saludos.
definitivamente asi no se hace en CDECL. (ni en stdcall, ni en fastcall... ni en ningun lado que conozca)
Citar
pop eax ; dirección de retorno
pop ecx ;primer parametro
pop edx ;segundo parametro
push eax
invoke MessageBoxA,0,edx,ecx,0
La forma facil seria:
void PrintInts( int amount, ...)
{
__asm mov eax, [ebp+08h]//valor primero, amount
__asm mov eax, [ebp+0Ch]//valor segundo
__asm mov eax,[ebp+010h]//valor tercero...
}
Visual Studio se encarga de inicializar (push ebp, mov ebp esp)
Tambien, en realidad lo hace de la siguiente manera, colocando comprobaciones de la pila de por medio.
lea eax,dword ptr [ebp+08h]
add eax, 4 //apunta al segundo parametro
add eax, 4// apunta al tercer parametro
add eax, 4// apunta al cuarto parametro
Depura este ejemplo:
http://www.cplusplus.com/reference/clibrary/cstdarg/va_start/
y se te solucionaran todas las dudas. Te conviene convertir ese ejemplo de float a int.
Son diferentes formas de hacerlo... de la forma que yo púse tambien se puede hacer pero si tienes muchos parametros es mas lio obviamente :P
PD: tambien sirve con stdcall y etc.
saludos.
Tu forma sirve unicamente para stdcall ya que la propia funcion limpia la pila. Stdcall no admite numero de parametros variables. (sobre esto va el hilo, nro prametros variables)
ahora, si estas en C/C++, y usas cdecl, el que llama la funcion limpia la pila. Si se usa tu metodo, la plia muere.
Y este hilo siempre fue sobre funciones en C con parametros variables. NO STDCALL