关于 go 在 Linux , amd64 平台下的系统调用问题
正常来说,系统调用传参顺序是
EDI, ESI, EDX, ECX, R8, R9
看clone的系统调用时,发现传参顺序为 EDI, ESI, EDX, R10, R8, R9, R12
请问有什么原因吗
正常来说,系统调用传参顺序是
EDI, ESI, EDX, ECX, R8, R9
看clone的系统调用时,发现传参顺序为 EDI, ESI, EDX, R10, R8, R9, R12
请问有什么原因吗
[clone]( https://github.com/golang/go/blob/release-branch.go1.15/src/runtime/sys_linux_amd64.s#L592)
从这里来看,R8, R9, R12 都被后面新创建的 client thread 使用了
[clone system call]( https://man7.org/linux/man-pages/man2/clone.2.html)
从 man page 看 clone 系统调用有 4 个参数。。。之前看错了。。。一直以为 clone 有 7 个参数
那么刚好对应 DI, SI, DX R10,分别是 int (*fn)(void *), void *stack, int flags, void *arg
这个问题大体上是解决了
剩下的一个小问题就是, 为什么不用 CX 和 R11
注释里有说
// Careful: Linux system call clobbers CX and R11.
这有什么原因吗?
————————————–arch/x86/entry.S————————————-
* 64-bit SYSCALL saves rip to rcx, clears rflags.RF, then saves rflags to r11,
* then loads new ss, cs, and rip from previously programmed MSRs.
* rflags gets masked by a value from another MSR (so CLD and CLAC
* are not needed). SYSCALL does not save anything on the stack
* and does not change rsp.
*
* Registers on entry:
* rax system call number
* rcx return address
* r11 saved rflags (note: r11 is callee-clobbered register in C ABI)
* rdi arg0
* rsi arg1
* rdx arg2
* r10 arg3 (needs to be moved to rcx to conform to C ABI)
* r8 arg4
* r9 arg5
* (note: r12-r15, rbp, rbx are callee-preserved in C ABI)
————————————————————————————————
内核模式调用约定( 系统调用 ) 是 rdi,rsi,rdx,r10,r8 和 r9
你用 c 写个 printf 的程序看下汇编就懂了。