elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Estamos en la red social de Mastodon


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  ¿Como es posible retornar estructuras con la convencion de llamadas cdecl?
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: ¿Como es posible retornar estructuras con la convencion de llamadas cdecl?  (Leído 3,725 veces)
Usuario887


Desconectado Desconectado

Mensajes: 310


Ver Perfil
¿Como es posible retornar estructuras con la convencion de llamadas cdecl?
« en: 6 Marzo 2021, 22:46 pm »

Tengo una pequeña duda...

En C es posible hacer esto:

Código
  1. /*...*/
  2. struct _hdr
  3. char data1;
  4. double data2;
  5. char *data3;
  6. };
  7.  
  8. /*...*/
  9.  
  10. struct _hdr foo (void)
  11. {
  12.    struct _hdr instance;
  13.    /*...*/
  14.    return instance;
  15. }
  16. /*...*/

¿Como es posible hacerlo segun la convencion de llamadas de C?

Citar
Integer values and memory addresses are returned in the EAX register
https://en.wikipedia.org/wiki/X86_calling_conventions

Entiendo que una estructura no es un valor entero (a menos que sea una direccion de memoria). Entonces, ¿Como haciendo uso de cdecl se puede retornar una estructura entera? La citada en el codigo no cabe siquiera en EDX:EAX.

Saludos y gracias por su atencion.


En línea

Eternal Idol
Kernel coder
Moderador
***
Desconectado Desconectado

Mensajes: 5.966


Israel nunca torturó niños, ni lo volverá a hacer.


Ver Perfil WWW
Re: ¿Como es posible retornar estructuras con la convencion de llamadas cdecl?
« Respuesta #1 en: 7 Marzo 2021, 09:43 am »

Es a gusto del compilador.

Citar
In regard to how to return values, some compilers return simple data structures with a length of 2 registers or less in the register pair EAX:EDX, and larger structures and class objects requiring special treatment by the exception handler (e.g., a defined constructor, destructor, or assignment) are returned in memory. To pass "in memory", the caller allocates memory and passes a pointer to it as a hidden first parameter; the callee populates the memory and returns the pointer, popping the hidden pointer when returning

https://en.wikipedia.org/wiki/X86_calling_conventions#cdecl

Código
  1. struct _hdr foo (void)
  2.    {
  3.        struct _hdr instance;
  4. instance.data1 = 'A';
  5. instance.data2 = 45.04;
  6. instance.data3 = "PROBANDO 123";
  7.        return instance;
  8.    }

Código
  1. void main()
  2. {
  3. foo();
  4. __debugbreak();
  5. }

Código
  1. 0:000> u main
  2. test!main [c:\src\test.c @ 26]:
  3. 00ffaa50 55              push    ebp
  4. 00ffaa51 8bec            mov     ebp,esp
  5. 00ffaa53 83ec18          sub     esp,18h
  6. 00ffaa56 8d45e8          lea     eax,[ebp-18h]
  7. 00ffaa59 50              push    eax
  8. 00ffaa5a e80e80ffff      call    test!ILT+6760(_foo) (00ff2a6d)
  9. 00ffaa5f 83c404          add     esp,4
  10. 00ffaa62 cc              int     3
  11. 00ffaa63 33c0            xor     eax,eax
  12. 00ffaa65 8be5            mov     esp,ebp
  13. 00ffaa67 5d              pop     ebp
  14. 00ffaa68 c3              ret

Al frenarse en el breakpoint:
0:000> dt test!_Hdr @eax
   +0x000 data1            : 65 'A'
   +0x008 data2            : 45.039999999999999147
   +0x010 data3            : 0x00cc3290  "PROBANDO 123"

Código
  1. 0:000> u test!foo
  2. test!foo [c:\src\test.c @ 15]:
  3. 00ffaa00 55              push    ebp
  4. 00ffaa01 8bec            mov     ebp,esp
  5. 00ffaa03 83ec18          sub     esp,18h
  6. 00ffaa06 c645e841        mov     byte ptr [ebp-18h],41h ;'A'
  7. 00ffaa0a f20f1005a88e0401 movsd   xmm0,mmword ptr [test!_real (01048ea8)] ;ver abajo
  8. 00ffaa12 f20f1145f0      movsd   mmword ptr [ebp-10h],xmm0
  9. 00ffaa17 c745f890320501  mov     dword ptr [ebp-8],offset test!__acrt_initial_multibyte_data+0x220 (01053290) ;ver abajo
  10. 00ffaa1e 8b4508          mov     eax,dword ptr [ebp+8]
  11. 00ffaa21 8b4de8          mov     ecx,dword ptr [ebp-18h]
  12. 00ffaa24 8908            mov     dword ptr [eax],ecx
  13. 00ffaa26 8b55ec          mov     edx,dword ptr [ebp-14h]
  14. 00ffaa29 895004          mov     dword ptr [eax+4],edx
  15. 00ffaa2c 8b4df0          mov     ecx,dword ptr [ebp-10h]
  16. 00ffaa2f 894808          mov     dword ptr [eax+8],ecx
  17. 00ffaa32 8b55f4          mov     edx,dword ptr [ebp-0Ch]
  18. 00ffaa35 89500c          mov     dword ptr [eax+0Ch],edx
  19. 00ffaa38 8b4df8          mov     ecx,dword ptr [ebp-8]
  20. 00ffaa3b 894810          mov     dword ptr [eax+10h],ecx
  21. 00ffaa3e 8b55fc          mov     edx,dword ptr [ebp-4]
  22. 00ffaa41 895014          mov     dword ptr [eax+14h],edx
  23. 00ffaa44 8b4508          mov     eax,dword ptr [ebp+8]
  24. 00ffaa47 8be5            mov     esp,ebp
  25. 00ffaa49 5d              pop     ebp
  26. 00ffaa4a c3              ret

0:000> dD 01048ea8 l1
01048ea8                   45.04
0:000> da 01053290
01053290  "PROBANDO 123"

Ahora podes probar sacando data2 de la estructura, data1 sera devuelto en EAX y data3 en EDX.


En línea

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón
Usuario887


Desconectado Desconectado

Mensajes: 310


Ver Perfil
Re: ¿Como es posible retornar estructuras con la convencion de llamadas cdecl?
« Respuesta #2 en: 7 Marzo 2021, 12:54 pm »

Supuse que se trataba de algo asi. No entiendo el codigo que usa el set de instrucciones MMX, pero entiendo lo que esta haciendo.

Aunque sinceramente pense que hacia uso de un ciclo para guardar los datos byte a byte.

Citar
Ahora podes probar sacando data2 de la estructura, data1 sera devuelto en EAX y data3 en EDX.

Me parece impresionante lo exhaustiva que llega a ser la tecnologia.

Saludos y gracias por tu respuesta.
En línea

Eternal Idol
Kernel coder
Moderador
***
Desconectado Desconectado

Mensajes: 5.966


Israel nunca torturó niños, ni lo volverá a hacer.


Ver Perfil WWW
Re: ¿Como es posible retornar estructuras con la convencion de llamadas cdecl?
« Respuesta #3 en: 7 Marzo 2021, 13:19 pm »

Aunque sinceramente pense que hacia uso de un ciclo para guardar los datos byte a byte.

A la larga lo terminara haciendo si la estructura es suficientemente extensa.

De nadas  ::)
En línea

La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón
BloodSharp


Desconectado Desconectado

Mensajes: 812


¡ Hiperfoco !


Ver Perfil WWW
Re: ¿Como es posible retornar estructuras con la convencion de llamadas cdecl?
« Respuesta #4 en: 7 Marzo 2021, 16:28 pm »

A ver que pasa con GCC:

Código
  1. #include <stdio.h>
  2.  
  3. struct _hdr
  4. {
  5.    char data1;
  6.    double data2;
  7.    char* data3;
  8. };
  9.  
  10. struct _hdr __attribute__((__cdecl__)) foo()
  11. {
  12.    struct _hdr instance;
  13. instance.data1 = 'A';
  14. instance.data2 = 45.04;
  15. instance.data3 = (char*)"PROBANDO 123";
  16.    return instance;
  17. }
  18.  
  19. int __attribute__((noinline)) __attribute__((__cdecl__)) foo2(int a, int b)
  20. {
  21.    return 0;
  22. }
  23.  
  24. int main(int argc,char*argv[])
  25. {
  26.    struct _hdr estructura;
  27.    int entero=foo2(1,2);
  28.    estructura=foo();
  29.    printf("%c %.2f %s %i\n",estructura.data1,estructura.data2,estructura.data3,entero);
  30.    return 0;
  31. }

Al parecer una función común y corriente como foo2 en cdecl funciona perfectamente, pero es interesante ver lo que pasa con foo:



Está pasando un puntero como argumento, lo interesante es que al parecer GCC cambia la convención a tipo stdcall:



Si arreglo y paso como parametro el puntero a la estructura vemos como el descompilador funciona casi retornando el mismo código original:



Por lo que en este caso aunque además de retornar la dirección del puntero (aunque no es usado) a la estructura también trabaja con un argumento oculto.


B#
« Última modificación: 7 Marzo 2021, 16:30 pm por BloodSharp » En línea



Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
¿Como retornar a un paso anterior?
Programación C/C++
skatres 5 2,593 Último mensaje 20 Noviembre 2011, 22:31 pm
por RyogiShiki
LINE sigue ampliando terreno: ya es posible realizar llamadas desde cualquier...
Noticias
wolfbcn 0 1,760 Último mensaje 7 Diciembre 2012, 17:25 pm
por wolfbcn
como retornar un int como un string c++?
Programación C/C++
andrex.125 2 3,583 Último mensaje 16 Mayo 2013, 20:26 pm
por andrex.125
Como retornar una matriz.
Programación C/C++
SirLancelot53 7 3,438 Último mensaje 24 Enero 2014, 04:07 am
por SirLancelot53
Estructuras dentro de Estructuras (Visual Basic 2013)
.NET (C#, VB.NET, ASP)
Tazmania40 0 1,867 Último mensaje 3 Marzo 2017, 21:44 pm
por Tazmania40
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines