Win64/Linux64/Win32下形参入栈规则

Registers and Stack

The CPU (x86, SPARC), word size (ILP32, LP64), and OS (Windows, Solaris, Linux) together determine how native (C-style) calls are made. On systems which support argument registers, leftward arguments are packed into registers until the registers run out, and then stack locations are used. On ILP32 systems, longs and doubles are passed as pairs of 32-bit arguments.

valuex86_32x86_64sparc (W=4/8)
native spESPRSPO6
return pcESP(0)RSP(0)O7
int resultEAXRAXO0
long resultEDX:EAXRAXO0:O1 / O0
float resultFPR1XMM0F0
reg. int argsnone(see below)O0…O5
reg. long argsnonesame as intsint pairs / ints
reg. float argsnone(see below)none / F0…F15
stack arg #iESP(4+i*4)RSP(8+i*8)SP(92/176+i*W)
sp alignment16 bytes16 bytes2*W bytes

On x86 LP64 systems, as many as the first 6 non-float and first 8 float arguments are allocated to registers.

reg. argint#0int#1int#2int#3int#4int#5float regs
WindowsRCXRDXR8R9nonenoneXMM0…XMM3
Lin/SolRDIRSIRDXRCXR8R9XMM0…XMM7

1.windows Win64

Integer arguments are passed in registers RCX, RDX, R8, and R9. Floating point arguments are passed in XMM0L, XMM1L, XMM2L, and XMM3L

1.1 Caller/Callee Saved Registers

The registers RAX, RCX, RDX, R8, R9, R10, R11 are considered volatile and must be considered destroyed on function calls (unless otherwise safety-provable by analysis such as whole program optimization).
The registers RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15 are considered nonvolatile and must be saved and restored by a function that uses them.

参考网址:http://kelvinh.github.io/blog/2013/08/05/windows-x64-calling-conventions/
参考网址:http://www.360doc.com/content/14/1221/21/3242454_434681142.shtml

1.2 形参的传递

a “register parameter area” [6] is provided by the caller in each stack frame. When a function is called, the last thing allocated on the stack before the return address is space for at least 4 registers (8 bytes each). This area is available for the callee’s use without explicitly allocating it. It’s useful for variable argument functions as well as for debugging (providing known locations for parameters, while registers may be reused for other purposes). Although the area was originally conceived for spilling the 4 arguments passed in registers, these days the compiler uses it for other optimization purposes as well (for example, if the function needs less than 32 bytes of stack space for its local variables, this area may be used without touching rsp).

argument n 对应 8*(n-1)+16(%rbp)

2 linux x86_x64

The first six integer or pointer arguments are passed in registers RDI, RSI, RDX, RCX, R8, R9 (R10 is used as a static chain pointer in case of nested functions[19]:21), while XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6 and XMM7 are used for certain floating point arguments.

2.1 Caller/Callee Saved Registers

r12, r13, r14, r15, rbx, rsp, rbp are the callee-saved registers - they have a “Yes” in the “Preserved across function calls” column.

参考网址:https://stackoverflow.com/questions/18024672/what-registers-are-preserved-through-a-linux-x86-64-function-call
参考网址:https://en.wikipedia.org/wiki/X86_calling_conventions
参考网址:https://stackoverflow.com/questions/2535989/what-are-the-calling-conventions-for-unix-linux-system-calls-on-i386-and-x86-6

2.2 形参的传递

long myfunc(long a, long b, long c, long d,
            long e, long f, long g, long h)
{
    long xx = a * b * c * d * e * f * g * h;
    long yy = a + b + c + d + e + f + g + h;
    long zz = utilfunc(xx, yy, xx % yy);
    return zz + 20;
}

argument n 对应 8*(n-7)+16(%rbp), 如图:
avatar

3. Windows x86_32

3.1 Caller/Callee Saved Registers

GCC expects functions to preserve the following callee-save registers:

    EBX, EDI, ESI, EBP, DS, ES, SS

You need not save the following registers:

    EAX, ECX, EDX, FS, GS, EFLAGS, floating point registers

参考网址:http://www.tenouk.com/Bufferoverflowc/Bufferoverflow2a.html
参考网址:https://wiki.openjdk.java.net/display/HotSpot/CallingSequences

3.2 形参的传递

int foobar(int a, int b, int c)
{
    int xx = a + 2;
    int yy = b + 3;
    int zz = c + 4;
    int sum = xx + yy + zz;

    return xx * yy * zz + sum;
}

int main()
{
    return foobar(77, 88, 99);
}

argument n 对应 (n-1)*4+8(%ebp), 如图:
avatar

附录A

1.what does eax have after mov eax,dword ptr [edi]

mov eax,dword ptr [edi]

Also, here is what’s store in edi.

0:024> dd edi
6090f454  0c0e8fe0 ffffffff 00000000 00000000

The line:
mov eax,dword ptr [edi]
will simply load whatever is stored at the address edi. So it’s a simple data load.

Since you don’t show what is at address edi (0x6090F434), we can’t tell you exactly what eax will be.

Based on the C++ code that is given, it looks like edi is the address of the num field. So it’s reading num into a register, then comparing it against 0xFFFFFFFF which is the INVALID_FLAG constant.

附录B

markdown在线表格转换:https://tool.lu/tables/

参考网址:http://cons.mit.edu/fa17/x86-64-architecture-guide.html
参考网址:https://eli.thegreenplace.net/2011/09/06/stack-frame-layout-on-x86-64/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值