Windows x64 calling convention
⚓ Rust 📅 2026-04-29 👤 surdeus 👁️ 4From the docs about Windows x64 calling convention:
The stack pointer must remain 16-byte aligned in any region of code that isn't part of an epilog or prolog, except within leaf functions.
So I tested with this code in godbolt:
#[unsafe(no_mangle)]
pub unsafe extern "win64" fn test() -> i64 {
unsafe { test2() }
}
#[unsafe(no_mangle)]
pub unsafe extern "win64" fn test2() -> i64 {
unsafe { test3(1, 2, 3, 4, 5) }
}
#[unsafe(no_mangle)]
pub unsafe extern "win64" fn test3(a: i64, b: i64, c: i64, d: i64, e: i64) -> i64 {
a + b + c + d + e
}
The compiler generated:
test2:
sub rsp, 40
mov ecx, 1
mov edx, 2
mov r8d, 3
mov r9d, 4
mov qword ptr [rsp + 32], 5
call test3
nop
add rsp, 40
ret
Why is sub rsp, 40 used here? Since 40 is not divisible by 16, doesn't that mean there is a time when the stack pointer does not align by 16 bytes?
3 posts - 2 participants
🏷️ Rust_feed