0
votes

According to the docs I can find on calling windows functions, the following applies:-

The Microsoft x64 calling convention[12][13] is followed on Windows and pre-boot UEFI (for long mode on x86-64). It uses registers RCX, RDX, R8, R9 for the first four integer or pointer arguments (in that order), and additional arguments are pushed onto the stack (right to left). Integer return values (similar to x86) are returned in RAX if 64 bits or less.

In the Microsoft x64 calling convention, it's the caller's responsibility to allocate 32 bytes of "shadow space" on the stack right before calling the function (regardless of the actual number of parameters used), and to pop the stack after the call. The shadow space is used to spill RCX, RDX, R8, and R9,[14] but must be made available to all functions, even those with fewer than four parameters.

The registers RAX, RCX, RDX, R8, R9, R10, R11 are considered volatile (caller-saved).[15]

The registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15 are considered nonvolatile (callee-saved).[15]

So, I have been happily calling kernel32 until a call to GetEnvironmentVariableA failed under certain circumstances. I finally traced it back to the fact that the direction flag DF was set and I needed to clear it.

I have not up till now been able to find any mention of this and wondered if it was prudent to always clear it before a call.

Or maybe that would cause other problems. Anyone aware of the conventions of calling in this instance?

1

1 Answers

3
votes

windows assume that the direction flag is cleared. despite in article said about C run-time only, this is true for whole windows (think because windows code itself primary written on c/c++). so when your programm begin execute - you can assume that DF is 0. usually you not need change this flag. however if you temporary change it (set to 1) in some internal routine, you must clear it by cld before call any windows api or any external module (because it assume that DF is 0).

all windows interrupts at very begin execution is clear DF to 0 - so this is safe temporary set DF to 1 in own internal code, main - before any external call reset it back to 0.