Question

I'm programming for Windows in assembly in NASM, and i found this in the code:

extern _ExitProcess@4
  ;Rest of code...
  ; ...
call  _ExitProcess@4

What does the @4 mean in the declaration and call of a winapi library function?

Was it helpful?

Solution

The winapi uses the __stdcall calling convention. The caller pushes all the arguments on the stack from right to left, the callee pops them again to cleanup the stack, typically with a RET n instruction.

It is the antipode of the __cdecl calling convention, the common default in C and C++ code where the caller cleans up the stack, typically with an ADD ESP,n instruction after the CALL. The advantage of __stdcall is that it is generates more compact code, just one cleanup instruction in the called function instead of many for each call to the function. But one big disadvantage: it is dangerous.

The danger lurks in the code that calls the function having been compiled with an out-dated declaration of the function. Typical when the function was changed by adding an argument for example. This ends very poorly, beyond the function trying to use an argument that is not available, the new function pops too many arguments off the stack. This imbalances the stack, causing not just the callee to fail but the caller as well. Extremely hard to diagnose.

So they did something about that, they decorated the name of the function. First with a leading _underscore, as is done for __cdecl functions. And appended @n, the value of n is the operand of the RET instruction at the end of the function. Or in other words, the number of bytes taken by the arguments on the stack.

This provides a linker diagnostic when there's a mismatch, a change in a foo(int) function to foo(int, int) for example generates the name _foo@8. The calling code not yet recompiled will look for a _foo@4 function. The linker fails, it cannot find that symbol. Disaster avoided.

OTHER TIPS

The name decoration scheme for C is documented at Format of a C Decorated Name. A decorated name containing a @ character is used for the __stdcall calling convention:

__stdcall: Leading underscore (_) and a trailing at sign (@) followed by a number representing the number of bytes in the parameter list

Tools like Dependency Walker are capable of displaying both decorated and undecorated names.

Unofficial documentation can be found here: Name Decoration

It's a name decoration specifying the total size of the function's arguments:

The name is followed by the at sign (@) followed by the number of bytes (in decimal) in the argument list.

(source)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top