duda con parametros sin definir y saber su direccion

Iniciado por asmnb, 14 Agosto 2011, 05:52 AM

0 Miembros y 1 Visitante están viendo este tema.

asmnb

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


MCKSys Argentina

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!
MCKSys Argentina

"Si piensas que algo está bien sólo porque todo el mundo lo cree, no estás pensando."


fary

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:

Código (asm) [Seleccionar]
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.
Un byte a la izquierda.

_Enko

#3
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.

fary

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.
Un byte a la izquierda.

_Enko


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