feature. See also
. The project being documented here (as the example) is the Zig library itself.
x86.syscall6
pub fn syscall6(
number: SYS,
arg1: syscall_arg_t,
arg2: syscall_arg_t,
arg3: syscall_arg_t,
arg4: syscall_arg_t,
arg5: syscall_arg_t,
arg6: syscall_arg_t,
) u32
File
Code
pub fn syscall6(
number: SYS,
arg1: syscall_arg_t,
arg2: syscall_arg_t,
arg3: syscall_arg_t,
arg4: syscall_arg_t,
arg5: syscall_arg_t,
arg6: syscall_arg_t,
) u32 {
// and there are no more GPRs available; so we'll need a memory operand for it. Adding that
// memory operand means that on PIC we might need a reference to the GOT, which in turn needs
// *its* own GPR, so we need to pass another arg in memory too! This is surprisingly hard to get
// right, because we can't touch esp or ebp until we're done with the memory input (as that
// input could be relative to esp or ebp).
const args56: [2]syscall_arg_t = .{ arg5, arg6 };
return asm volatile (
\\ push %[args56]
\\ push %%ebp
\\ mov 4(%%esp), %%ebp
\\ mov %%edi, 4(%%esp)
\\ // The saved %%edi and %%ebp are on the stack, and %%ebp points to `args56`.
\\ // Prepare the last two args, syscall, then pop the saved %%ebp and %%edi.
\\ mov (%%ebp), %%edi
\\ mov 4(%%ebp), %%ebp
\\ int $0x80
\\ pop %%ebp
\\ pop %%edi
: [ret] "={eax}" (-> u32),
: [number] "{eax}" (@backingInt(number)),
[arg1] "{ebx}" (arg1),
[arg2] "{ecx}" (arg2),
[arg3] "{edx}" (arg3),
[arg4] "{esi}" (arg4),
[args56] "rm" (&args56),
: .{ .memory = true });
}