Is reserving stack space necessary for functions l

2019-01-22 20:07发布

问题:

Just started learning x64 assembly and I have a question about functions, arguments, and the stack. As far as I understand it, the first four arguments in a function get passed to rcx, rdx, r8, and r9 registers (and xmm0-xmm3 for floats) in Windows. So a trivial addition function with four parameters would looks like this:

add:
   mov r10, rcx
   add r10, rdx
   add r10, r8
   add r10, r9
   mov rax, r10
   ret

However, I've come across documentation that mentions this:

At a minimum, each function must reserve 32 bytes (four 64-bit values) on the stack. This space allows registers passed into the function to be easily copied to a well-known stack location. The callee function isn't required to spill the input register params to the stack, but the stack space reservation ensures that it can if needed.

So, do I have to reserve stack space even if the functions I'm making take four parameters or less, or is it just a recommendation?

回答1:

Your quote is from the "calling convention" part of the documentation. At the very least, you do not have to worry about this if you do not call other functions from your assembly code. If you do, then you must respect, among other things, "red zone" and stack alignment considerations, that the recommendation you quote is intended to ensure.

EDIT: this post clarifies the difference between "red zone" and "shadow space".



回答2:

I just ran into this not knowing and it seems to be the case. The first two instructions in GetAsyncKeyState for instance overwrite the stack above the return value in the 0x20 byte area you're supposed to reserve for the callee to use for parameters:

user32.GetAsyncKeyState  - mov [rsp+08],rbx
user32.GetAsyncKeyState+5- mov [rsp+10],rsi
user32.GetAsyncKeyState+A- push rdi
user32.GetAsyncKeyState+B- sub rsp,20