Win64 和 Linux-x86_64 调用约定未使用的寄存器修改与否
Win64 and Linux-x86_64 Calling Convention Unused registers modified or not
我有一些关于 linux-x86_64 和 win64 中调用约定的重要问题。
我搜索了太多地方,但我没有找到问题的答案!
我认为我的问题没有重复,所以请先阅读。
在linux-x86_64中我们使用系统调用...
linux-x86_64 系统调用调用约定为:
RDI -> first parameter
RSI -> second parameter
RDX -> third parameter
R10 -> fourth parameter
R8 -> fifth parameter
R9 -> sixth parameter
R11 -> ... (for all syscalls)
RCX -> ... (for all syscalls)
RAX -> return
现在,我关于 linux-x86_64 的问题:
问题1:如果一个系统调用(例如,'sys_write
')需要3个参数(RDI,RSI,RDX
),那么其他参数寄存器呢?是的,这个系统调用只有 3 个参数,但它是否也会使用其他参数寄存器(用于其他用途,如内部进程和...)?我的意思是,如果我调用 sys_write
并且我在 R10
寄存器中有一些东西,那么 R10
值在系统调用之后会保持 100% 不变吗?这个系统调用没有第四个参数,所以我认为 R10 或 R8 或 R9 中的所有内容都将保持不变……对吗?我说得对吗?
问题2:比如sys_mkdir
...如果我要调用sys_mkdir
3次(一个接一个),是这样的正确吗?
mov eax, 83
mov rdi, .filename
mov esi, 0766o
syscall
mov eax, 83
mov rdi, .filename2
syscall ; no (mov esi, 0766o) anymore because ESI is equal to 0766o from last syscall
mov eax, 83
mov rdi, .filename3
syscall ; no (mov esi, 0766o) anymore because ESI is equal to 0766o from last syscall
在这里,我只是不再更新 ESI
... 因为我认为 syscall
保持参数寄存器不变。我说的对吗?
现在Win64,Win64调用约定为:
RCX -> first parameter
RDX -> second parameter
R8 -> third parameter
R9 -> fourth parameter
... (Stack)
问题1:这里,我关于win64调用约定的问题与第一个关于linux-x86_64的问题相同。例如,如果我只用 1 个参数调用 Some 函数,(例如 ExitProcess
)...其他参数寄存器值会保持不变吗?或者 windows 也将使用其他参数寄存器并且我在其中的值会改变?
A 的注册状态 call-preserved or call-clobbered 从不依赖于调用者实际传递的参数数量 and/or 被调用者期望的,在我看过的任何 ISA 的任何调用约定中,并且当然不是 x86 上的任何标准。
但是是的,原始系统调用的调用约定与函数的调用约定不同,即使对于可能的薄包装函数也是如此。
所有标准用户-space 函数调用约定都将所有参数传递寄存器(和堆栈槽)作为调用破坏。因此,如果您的 asm 使用 call
,这就是您所需要的。
主流操作系统的系统调用约定保留所有寄存器(return 值除外)。 (但在 x86-64 上,只有在 syscall
本身覆盖 RCX 和 R11 之后,。)如果你直接使用 syscall
或 int 0x80
或其他任何东西,这就是你应该期望的.
请注意 Windows 而不是 具有跨内核版本的稳定系统调用 ABI,并且不记录原始系统调用,因此在正常情况下 Windows 代码,你总是在进行 DLL 函数调用,而不是原始系统调用。 People have reverse-engineered the system calls for different Windows versions, though.
MacOS 也官方 没有 stable/documented 系统调用 ABI,但实际上 Darwin 基本上有,至少对于正常 POSIX open/read/write/close/exit 玩具程序使用的调用。
- What registers are preserved through a linux x86-64 function call
- What are the calling conventions for UNIX & Linux system calls (and user-space functions) on i386 and x86-64
- https://packagecloud.io/blog/the-definitive-guide-to-linux-system-calls/
- Where is the x86-64 System V ABI documented?
- Windows system calls
我有一些关于 linux-x86_64 和 win64 中调用约定的重要问题。 我搜索了太多地方,但我没有找到问题的答案! 我认为我的问题没有重复,所以请先阅读。
在linux-x86_64中我们使用系统调用...
linux-x86_64 系统调用调用约定为:
RDI -> first parameter
RSI -> second parameter
RDX -> third parameter
R10 -> fourth parameter
R8 -> fifth parameter
R9 -> sixth parameter
R11 -> ... (for all syscalls)
RCX -> ... (for all syscalls)
RAX -> return
现在,我关于 linux-x86_64 的问题:
问题1:如果一个系统调用(例如,'sys_write
')需要3个参数(RDI,RSI,RDX
),那么其他参数寄存器呢?是的,这个系统调用只有 3 个参数,但它是否也会使用其他参数寄存器(用于其他用途,如内部进程和...)?我的意思是,如果我调用 sys_write
并且我在 R10
寄存器中有一些东西,那么 R10
值在系统调用之后会保持 100% 不变吗?这个系统调用没有第四个参数,所以我认为 R10 或 R8 或 R9 中的所有内容都将保持不变……对吗?我说得对吗?
问题2:比如sys_mkdir
...如果我要调用sys_mkdir
3次(一个接一个),是这样的正确吗?
mov eax, 83
mov rdi, .filename
mov esi, 0766o
syscall
mov eax, 83
mov rdi, .filename2
syscall ; no (mov esi, 0766o) anymore because ESI is equal to 0766o from last syscall
mov eax, 83
mov rdi, .filename3
syscall ; no (mov esi, 0766o) anymore because ESI is equal to 0766o from last syscall
在这里,我只是不再更新 ESI
... 因为我认为 syscall
保持参数寄存器不变。我说的对吗?
现在Win64,Win64调用约定为:
RCX -> first parameter
RDX -> second parameter
R8 -> third parameter
R9 -> fourth parameter
... (Stack)
问题1:这里,我关于win64调用约定的问题与第一个关于linux-x86_64的问题相同。例如,如果我只用 1 个参数调用 Some 函数,(例如 ExitProcess
)...其他参数寄存器值会保持不变吗?或者 windows 也将使用其他参数寄存器并且我在其中的值会改变?
A 的注册状态 call-preserved or call-clobbered 从不依赖于调用者实际传递的参数数量 and/or 被调用者期望的,在我看过的任何 ISA 的任何调用约定中,并且当然不是 x86 上的任何标准。
但是是的,原始系统调用的调用约定与函数的调用约定不同,即使对于可能的薄包装函数也是如此。
所有标准用户-space 函数调用约定都将所有参数传递寄存器(和堆栈槽)作为调用破坏。因此,如果您的 asm 使用 call
,这就是您所需要的。
主流操作系统的系统调用约定保留所有寄存器(return 值除外)。 (但在 x86-64 上,只有在 syscall
本身覆盖 RCX 和 R11 之后,syscall
或 int 0x80
或其他任何东西,这就是你应该期望的.
请注意 Windows 而不是 具有跨内核版本的稳定系统调用 ABI,并且不记录原始系统调用,因此在正常情况下 Windows 代码,你总是在进行 DLL 函数调用,而不是原始系统调用。 People have reverse-engineered the system calls for different Windows versions, though.
MacOS 也官方 没有 stable/documented 系统调用 ABI,但实际上 Darwin 基本上有,至少对于正常 POSIX open/read/write/close/exit 玩具程序使用的调用。
- What registers are preserved through a linux x86-64 function call
- What are the calling conventions for UNIX & Linux system calls (and user-space functions) on i386 and x86-64
- https://packagecloud.io/blog/the-definitive-guide-to-linux-system-calls/
- Where is the x86-64 System V ABI documented?
- Windows system calls