### _Optlink Calling Convention

This is the default calling convention. It is an alternative to the _System convention that is normally used for calls to the operating system. It provides a faster call than the _System convention, while conforming to the ANSI and SAA language standards.

You can explicitly give a function the _Optlink convention with the _Optlink keyword.

Features of _Optlink

- Function names are prefixed with a leading ?.
- Parameters are pushed from right to left onto the stack to allow for varying length parameter lists without having to use hidden parameters.
- The caller cleans up the parameters.
- The direction flag must be clear upon entry to functions and clear on exit from functions. The state of the other flags is ignored on entry to a function and undefined on exit.

Tips for Using _Optlink

- Prototype all function declarations for better performance. The C++ language requires all functions to have prototypes.

  Note: All calls and functions must be prototyped consistently; that is, functions declared more than once must have identical prototypes. Otherwise, the results will be undefined.

- Place the conforming and floating-point parameters that are most heavily used lexically leftmost in the parameter list so they will be considered for registers first. If they are adjacent to each other, the preparation of the parameter list will be faster.
- If you have a parameter that is only used near the end of a function, put it at or near the end of the parameter list.
  - If all of your parameters are only used near the end of functions, consider using _System or __cdecl linkage.
  - If all of your parameters are only used near the end of functions, consider using __stdcall or __cdecl linkages.
- If you are passing structures by value, put them at the end of the parameter list.
- Avoid using variable arguments in nonprototype functions. This practice results in undefined behavior under the ANSI C standard.
- If you have a variable-length argument list, consider using _System linkage. It is faster in this situation.
- If you have a variable-length argument list, consider using __stdcall or __cdecl linkage. It is faster in this situation.
- Compile with optimization on (by specifying the /O compiler option).

Register Implications

- The general-purpose registers EBP, EBX, EDI, and ESI are preserved across the call.
- The general-purpose registers EAX, EDX, and ECX are not preserved across the call.
- Floating-point registers are not preserved across the call.
- The three conforming parameters that are lexically leftmost (conforming parameters are 1, 2, and 4-byte signed and unsigned integers, enumerations, and all pointer types) are passed in EAX, EDX, and ECX, respectively.
- Up to four floating-point parameters (the lexically first four) are passed in extended-precision format (80-bit) in the floating-point register stack. All other parameters are passed on the run-time stack.
- Space for the parameters in registers is allocated on the stack, but the parameters are not copied into that space.
- If there is no prototype or an incomplete prototype for the function called, an eyecatcher is placed after the call instruction to tell the callee how the register parameters correspond to the stack storage mapped for them. Fully prototyped code never needs eyecatchers.
- Conforming return values, with the exception of 64-bit integers, are returned in EAX. In the case of 64-bit integers, the most significant 32 bits are returned in EDX and the least significant 32 bits are returned in EAX.
- Floating-point return values are returned in extended-precision format in the topmost register of the floating-point stack.
- When you call external functions, the floating-point register stack contains only valid parameter registers on entry and valid return values on exit. (When you call functions in the current compilation unit that do not call any other functions, this state may not be true.)
- Under some circumstances, the compiler will not use EBP to access automatic and parameter values, thus increasing the efficiency of the application. Whether it is used or not, EBP will not change across the call.
- Calls with aggregates returned by value pass a hidden first parameter that is the address of a storage area determined by the caller. This area becomes the returned aggregate. The hidden pointer parameter is always considered "nonconforming", and is not passed in a register. The called function must load it into EAX before returning.
- The compiler will not change the contents of the floating-point control register. If you want to change the control register contents for a particular operation, save the contents before making the changes and restore them after the operation.
- In a prototyped function taking a variable number of parameters (that is, one whose parameter list ends in an ellipsis), only the parameters preceding the ellipsis are eligible to be passed in registers.

Calling Conventions
Eyecatchers
Overview of Optimization

Examples of Passing Parameters Using _Optlink