Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fastcall: What happens with the stack?

I'm currently learning x64 assembly by myself and have trouble understanding what happen with the stack when calling an assembly procedure from c++.

From what I currently understand from MSDN and Intel, the first 4 integer/floating point parameters are stored in the rcx/xmm0, rdx/xmm1, r8/xmm2 and r9/xmm3 registers and all others will be placed on the stack.

I just do not understand why i have to access the 5th parameter 40 bytes from rsp [rsp+28h] instead of just 8 since the first 32 bytes are accessed in registers.

Can someone explain me what actually happens?

Thank you.

like image 869
Deltgen David Avatar asked Feb 24 '14 15:02

Deltgen David


People also ask

What do we store on the stack in our calling convention?

If the callee takes more than six arguments, or if some of its arguments are large, the caller must store the surplus arguments on its stack frame. It stores these in increasing order, so that the 7th argument has a smaller address than the 8th argument, and so forth.

What is __ Fastcall in C++?

The __fastcall calling convention specifies that arguments to functions are to be passed in registers, when possible. This calling convention only applies to the x86 architecture.

Is Fastcall faster?

Since it typically saves at least four memory accesses, yes it is generally faster.

Which registers do we need to preserve using the stack before the function call?

The registers labeled “callee-saved” must be saved by a function if it needs to modify them, and then restored to their original values before return. The usual way to save the callee-saved registers (only the ones you use in your function need to be saved, of course), is to push them onto the stack.


1 Answers

The key is in this phrase from the linked MSDN:

The x64 Application Binary Interface (ABI) is a 4 register fast-call calling convention, with stack-backing for those registers.

That is, the registers are loaded with the first 4 arguments, but nevertheless they have its space reserved in the stack. As @HansPassant notes in the comments below, the caller does not write into this shadow space, but it is available for the callee, should it need to save the registers (for example for calling another function).

like image 141
rodrigo Avatar answered Sep 28 '22 00:09

rodrigo