7

I'm learning x64 assembly on Windows for 'fun'. The MSDN documentation for the x64 calling convention on Windows says:

The caller is responsible for allocating space for parameters to the callee, and must always allocate sufficient space for the 4 register parameters, even if the callee doesn’t have that many parameters. This aids in the simplicity of supporting C unprototyped functions, and vararg C/C++ functions.

As my functions are not C unprototyped functions or varargs C/C++ functions, does this mean I can always use [rsp+8] to [rsp+32] (assuming an unmodified value of rsp right after a call) for general purpose storage within my function, like for local variables?

Trillian
  • 6,207
  • 1
  • 26
  • 36

2 Answers2

6

Yes, you can use inbound parameter scratch space for any purpose. But you knew this already: Permission to do this is already implied by the legality of modifying inbound parameters.

void somefunction(int arg1)
{
    arg1 = anyvalue; // mov [rsp+8], anyvalue
}
Raymond Chen
  • 44,448
  • 11
  • 96
  • 135
  • Thanks for the clear answer. However modifying inbound parameters would rather be `mov rcx, anyvalue` as the argument is passed via `rcx`, which is why I was unsure about `[rsp+8]`. – Trillian Aug 21 '11 at 14:20
  • 3
    But you're also permitted to spill inbound parameters. That's why the reserved space is there, after all. `void somefunction(int arg1) { /* spill: mov [rsp+8], rcx */ arg1 = anyvalue; /* mov [rsp+8], anyvalue */ }` – Raymond Chen Aug 21 '11 at 15:01
1

I think what he is trying to do is more something like this:

*(decltype(&anyvalue))((PBYTE)&arg1+8) = anyvalue; // mov [rsp+8+8], anyvalue

As far as I understand, Microsoft states that you are required to allocate enough space for the callee to store four registers (rcx, rdx, r8. r9), even in a function that takes only one argument (in rcx).

Note: i'm sorry about the ugly c code and the old-school casting mixed with the new decltype keyword

Griwes
  • 8,805
  • 2
  • 43
  • 70
nts94
  • 11
  • 1