En CDECL, los argumentos se insertan en la pila en orden inverso, la persona que llama borra la pila y el resultado se devuelve a través del registro del procesador (luego lo llamaré "registro A"). En STDCALL hay una diferencia, la persona que llama no borra la pila, la calle sí.
Estás preguntando cuál es más rápido. Ninguno. Debe usar la convención de llamadas nativas siempre que pueda. Cambie la convención solo si no hay salida, cuando utilice bibliotecas externas que requieran el uso de cierta convención.
Además, hay otras convenciones que el compilador puede elegir como predeterminada, es decir, el compilador de Visual C ++ usa FASTCALL, que en teoría es más rápido debido al uso más extenso de los registros del procesador.
Por lo general, debe dar una firma de convención de llamada adecuada a las funciones de devolución de llamada pasadas a alguna biblioteca externa, es decir, la devolución de llamada qsort
desde la biblioteca C debe ser CDECL (si el compilador usa otra convención por defecto, debemos marcar la devolución de llamada como CDECL) o se deben realizar varias devoluciones de llamada de WinAPI. STDCALL (todo WinAPI es STDCALL).
Otro caso habitual puede ser cuando está almacenando punteros a algunas funciones externas, es decir, para crear un puntero a la función WinAPI, su definición de tipo debe estar marcada con STDCALL.
Y a continuación hay un ejemplo que muestra cómo lo hace el compilador:
i = Function(x, y, z);
int Function(int a, int b, int c) { return a + b + c; }
CDECL:
push on the stack a copy of 'z', then a copy of 'y', then a copy of 'x'
call (jump to function body, after function is finished it will jump back here, the address where to jump back is in registers)
move contents of register A to 'i' variable
pop all from the stack that we have pushed (copy of x, y and z)
copy 'a' (from stack) to register A
copy 'b' (from stack) to register B
add A and B, store result in A
copy 'c' (from stack) to register B
add A and B, store result in A
jump back to caller code (a, b and c still on the stack, the result is in register A)
STDCALL:
push on the stack a copy of 'z', then a copy of 'y', then a copy of 'x'
call
move contents of register A to 'i' variable
pop 'a' from stack to register A
pop 'b' from stack to register B
add A and B, store result in A
pop 'c' from stack to register B
add A and B, store result in A
jump back to caller code (a, b and c are no more on the stack, result in register A)