Convención de llamadas

La versión actual de la página aún no ha sido revisada por colaboradores experimentados y puede diferir significativamente de la versión revisada el 11 de agosto de 2018; las comprobaciones requieren 37 ediciones .

Convención de llamada ( esp.  convención de llamada ): una descripción de las características técnicas de las subrutinas de llamada , que define:

Es parte de la interfaz binaria de la aplicación ( ABI) . 

Composición

La convención de llamada describe lo siguiente:

La convención de llamadas se puede describir en la documentación de la arquitectura ABI , en la documentación del sistema operativo o en la documentación del compilador .

Uso

Convenciones de llamada utilizadas en x86 para direccionamiento de 32 bits

La lista está incompleta, se presentan los principales acuerdos utilizados hasta el día de hoy.

Para las convenciones enumeradas a continuación (excepto ), la subrutina debe restaurar los valores del segmento registra , registra y cdeclantes de devolver los valores de la función . Es posible que no se restablezcan los valores de otros registros . espebp

Si el valor de retorno de la función es menor o igual que el tamaño de un registro eax , el valor de retorno se almacena en un registro eax . De lo contrario, el valor de retorno se almacena en la parte superior de la pila y el puntero a la parte superior de la pila se almacena en el registro eax . Si se devuelve un objeto con un autodestructor (cualquier objeto C++ con un destructor no nulo , cadenas de longitud arbitraria en Pascal, BSTR en WinAPI , etc.), la persona que llama debe destruirlo correctamente.

cdecl

cdecl(abreviatura de c - declaración en inglés  ) es una convención de llamada utilizada por los compiladores para el lenguaje C (de ahí el nombre).

Los argumentos de función se pasan a través de la pila, de derecha a izquierda. Los argumentos de menos de 4 bytes se expanden a 4 bytes. El programa de llamada limpia la pila . Esta es la forma principal de llamar a funciones con un número variable de argumentos (por ejemplo, printf()). Los métodos para obtener el valor de retorno de una función se dan en la tabla.

Tipo de Tamaño del valor de retorno, bytes Método de paso de valor de retorno Nota
entero, puntero 1, 2, 4 A través del registro eax Los valores menores de 4 bytes se expanden a 4 bytes
Entero ocho A través de un par de registros edx:eax
número de coma flotante 4, 8 Vía registro (desde x87st0 pseudostack , FPU )
Otro más de 8 A través del registro eax Un puntero a una estructura de datos se almacena en un registro eax

Antes de llamar a la función , se inserta un código llamado prólogo ( prolog en inglés  ) y realiza las siguientes acciones:

Después de llamar a la función , se inserta un código llamado epílogo ( epílogo en inglés  ) y realiza las siguientes acciones:

pascual

pascal es una convención de llamada utilizada por los compiladores del lenguaje Pascal . También se utiliza en Windows 3.x.

Los argumentos de los procedimientos y funciones se pasan a través de la pila, de izquierda a derecha. El puntero a la parte superior de la pila (el valor del registro esp ) a la posición inicial es devuelto por la subrutina llamada . Los parámetros modificables sólo se pasan por referencia . El valor devuelto se pasa a través del parámetro Result mutable. El parámetro Result se crea implícitamente y es el primer argumento del .

stdcall o winapi

stdcallo eswinapi  la convención de llamada utilizada por Windows para llamar a las funciones de WinAPI .

Los argumentos de función se pasan a través de la pila, de derecha a izquierda. La pila es limpiada por la subrutina llamada .

llamada rapida

fastcall - el nombre general para convenciones que pasan parámetros a través de registros (por lo general, esta es la forma más rápida de ejecutar una computadora, de ahí el nombre (aquí el prefijo " rápido " en inglés se traduce como " rápido ", y " llamada " en inglés se traduce como " llamada "). Es decir, traducido literalmente como " llamada rápida ")). Si no hay suficientes registros para guardar todos los parámetros y resultados intermedios, entonces se usa adicionalmente la pila.

La convención de llamada fastcallno está estandarizada, por lo que solo se usa para llamar a procedimientos y funciones que no se exportan desde el módulo ejecutable ni se importan desde el exterior.

En los compiladores de Borland , por la convención __fastcall, también llamada register[5] , los parámetros se pasan de izquierda a derecha en los registros eax , edxy ecx, si hay más de tres parámetros, en la pila, también de izquierda a derecha . El valor inicial del puntero a la parte superior de la pila ( valor de registro esp ) es devuelto por la subrutina llamada .

En la versión de 32 bits del compilador Microsoft [6] , así como en el compilador GCC [ 7] , la convención , también llamada , especifica que los dos primeros parámetros se pasan de izquierda a derecha en los registros y , y el resto Los parámetros se pasan de derecha a izquierda en la pila. La pila es limpiada por la subrutina llamada . __fastcall__msfastcall ecxedx

llamada segura

safecall es una convención de llamada utilizada para llamar a métodos de interfaces COM .

Los métodos de la interfaz COM son funciones que devuelven un tipo HRESULT . El código agregado después de la llamada a la función analiza el valor de retorno. Si hay un error, el código registra el código de error, el mensaje de error y genera una excepción . De lo contrario, el valor de retorno real se oculta y, en su lugar, se utiliza el último parámetro pasado a la función por referencia . Por ejemplo, las siguientes dos declaraciones de funciones pueden considerarse equivalentes.

// función de llamada segura Hacer Algo ( a : DWORD ) : DWORD ; llamada segura ; // función de simulación de llamada segura DoSomething ( a : DWORD ; out Result : DWORD ) : HResult ; llamada estándar ;

esta llamada

thiscall es una convención de llamada utilizada por los compiladores del lenguaje C++ cuando llaman a métodos de clase en la programación orientada a objetos .

Los argumentos de función se pasan a través de la pila, de derecha a izquierda. La pila es limpiada por la función llamada . La convención thiscalldifiere de la stdcallconvención solo en que el puntero al objeto en el que se invoca el método ( puntero this ) se escribe en el registro ecx[8] .

Véase también

  • libffi  es una biblioteca para llamar a funciones usando varias convenciones.

Notas

  1. 1 2 Los argumentos pequeños son valores cuyo tamaño es menor o igual al tamaño de un registro del procesador . Por ejemplo, 1, 2 y 4  bytes para un procesador x86 que se ejecuta en modo de 32 bits.
  2. 1 2 Los argumentos grandes son valores que son más grandes que el tamaño de un registro de procesador . Por ejemplo, 8 bytes o más para un procesador x86 que se ejecuta en modo de 32 bits.
  3. Prólogo :  código que guarda registros , pasa argumentos a una función y coloca variables locales en la pila de funciones.
  4. Epilogue ( eng.  epilogue ): código que devuelve el control a la función que llama, borra la pila, restaura los valores de registro , transfiere el valor de retorno de la función.
  5. Control de programa: Convención de registro . docwiki.embarcadero.com (1 de junio de 2010). Fecha de acceso: 27 de septiembre de 2010. Archivado desde el original el 20 de noviembre de 2012.
  6. _llamada rápida . msdn.microsoft.com. Fecha de acceso: 27 de septiembre de 2010. Archivado desde el original el 20 de noviembre de 2012.
  7. Ohse, Uwe descripción general de atributos gcc: función fastcall . ohse.de. Fecha de acceso: 27 de septiembre de 2010. Archivado desde el original el 20 de noviembre de 2012.
  8. esta llamada (C++  ) . msdn.microsoft.com.

Enlaces