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

时间:2022-09-01 11:09:32

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.

value x86_32 x86_64 sparc (W=4/8)
native sp ESP RSP O6
return pc ESP(0) RSP(0) O7
int result EAX RAX O0
long result RAX / O0
float result FPR1 XMM0 F0
reg. int args none (see below) O0..O5
reg. long args none same as ints int pairs / ints
reg. float args none (see below) none / F0..F15
stack arg #i ESP(4+i*4) RSP(8+i*8) SP(92/176+i*W)
sp alignment 16 bytes 16 bytes 2*W bytes

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

reg. arg int#0 int#1 int#2 int#3 int#4 int#5 float regs
Windows RCX RDX R8 R9 none none XMM0..XMM3
Lin/Sol RDI RSI RDX RCX R8 R9 XMM0..XMM7

1.win dows 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

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

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

附录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/