有一个问题一直困扰着我。
那就是...为什么在 x86_32 中,参数会按照我感觉上是字母表顺序(eax
, ecx
, edx
, esi
)和等级顺序(esi
, edi
, ebp
)来传递。
+---------+------+------+------+------+------+------+
| syscall | arg0 | arg1 | arg2 | arg3 | arg4 | arg5 |
+---------+------+------+------+------+------+------+
| %eax | %ebx | %ecx | %edx | %esi | %edi | %ebp |
+---------+------+------+------+------+------+------+
section .text
global _start
_start:
mov eax, 1 ; x86_64 opcode for sys_exit
mov ebx, 0 ; first argument
int 0x80
在 x86_64 中,系统调用的参数通过一些看起来有点 随意 排列的寄存器传递:
+---------+------+------+------+------+------+------+
| syscall | arg0 | arg1 | arg2 | arg3 | arg4 | arg5 |
+---------+------+------+------+------+------+------+
| %rax | %rdi | %rsi | %rdx | %r10 | %r8 | %r9 |
+---------+------+------+------+------+------+------+
section .text
global _start
_start:
mov eax, 1 ; x86_64 opcode for sys_exit
mov edi, 0 ; first argument
syscall
他们这样做是有特定的原因吗?我有没有看漏什么?
ebx
是调用保留的,因此几乎每个系统调用包装器都需要保存/恢复ebx)。 - Peter Cordesrep movsb
实现memcpy
时的寄存器移动量等问题。 - fuz