Jinoh Kang (@iamahuman) commented about dlls/ntdll/tests/exception.c:
0x55, /* push %rbp; 8*7(rsp) */
0x56, /* push %rsi; 8*6(rsp) */
0x57, /* push %rdi; 8*5(rsp) */
0x41, 0x54, /* push %r12; 8*4(rsp) */
0x41, 0x55, /* push %r13; 8*3(rsp) */
0x41, 0x56, /* push %r14; 8*2(rsp) */
0x41, 0x57, /* push %r15; 8*1(rsp) */
0x48, 0x83, 0xec, 0x08, /* sub $0x8, %rsp; reserve space for rsp */
0x48, 0x89, 0x24, 0x24, /* mov %rsp, (%rsp); for stack validation */
/* save args */
0x48, 0x89, 0x4c, 0x24, 0x50, /* mov %rcx, 8*10(%rsp) */
0x48, 0x89, 0x54, 0x24, 0x58, /* mov %rdx, 8*11(%rsp) */
0x4c, 0x89, 0x44, 0x24, 0x60, /* mov %r8, 8*12(%rsp) */
0x4c, 0x89, 0x4c, 0x24, 0x68, /* mov %r9, 8*13(%rsp) */
We still need to reserve outgoing register parameter save area for our callees (RtlCaptureContext, NtContinue).[^note] All non-leaf functions are required by x64 MS ABI to reserve home area for callees.
```suggestion:-19+0 /* ret at 8*13(rsp) */
/* need to preserve these */ 0x53, /* push %rbx; 8*12(rsp) */ 0x55, /* push %rbp; 8*11(rsp) */ 0x56, /* push %rsi; 8*10(rsp) */ 0x57, /* push %rdi; 8*9(rsp) */ 0x41, 0x54, /* push %r12; 8*8(rsp) */ 0x41, 0x55, /* push %r13; 8*7(rsp) */ 0x41, 0x56, /* push %r14; 8*6(rsp) */ 0x41, 0x57, /* push %r15; 8*5(rsp) */
0x48, 0x83, 0xec, 0x28, /* sub $0x28, %rsp; reserve space for rsp and outgoing reg params */ 0x48, 0x89, 0x64, 0x24, 0x20, /* mov %rsp, 8*4(%rsp); for stack validation */
/* save args */ 0x48, 0x89, 0x4c, 0x24, 0x70, /* mov %rcx, 8*14(%rsp) */ 0x48, 0x89, 0x54, 0x24, 0x78, /* mov %rdx, 8*15(%rsp) */ 0x4c, 0x89, 0x84, 0x24, 0x80, 0x00, 0x00, 0x00, /* mov %r8, 8*16(%rsp) */ 0x4c, 0x89, 0x8c, 0x24, 0x88, 0x00, 0x00, 0x00, /* mov %r9, 8*17(%rsp) */ ```
[^note]: Yes, neither functions rarely ever need to modify its home area, but this is never guaranteed by future Windows versions.