关于 go 在 Linux , amd64 平台下的系统调用问题

2020-09-15 16:00:21 +08:00
 chanchancl

正常来说,系统调用传参顺序是

EDI, ESI, EDX, ECX, R8, R9

clone的系统调用时,发现传参顺序为 EDI, ESI, EDX, R10, R8, R9, R12

请问有什么原因吗

1785 次点击
所在节点    Go 编程语言
5 条回复
chanchancl
2020-09-15 16:15:33 +08:00
比较了一下,发现我手里的 go1.15.1 的源码,和连接里的 go1.15.2 的代码又不一样了。。。
这些寄存器里到底哪些是传参的。。哪些是作为共享用的呢?
chanchancl
2020-09-15 16:48:23 +08:00
以 1.15 branch 作为标准

[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.

这有什么原因吗?
katsusan
2020-09-15 18:40:46 +08:00
linux 内核文档写的很清楚,RCX 和 R11 会在 x86_64 系统调用时被内核使用。

--------------------------------------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)
------------------------------------------------------------------------------------------------
Mohanson
2020-09-16 09:53:27 +08:00
用户模式调用约定( calling convention ) 是 EDI, ESI, EDX, ECX, R8, R9

内核模式调用约定( 系统调用 ) 是 rdi,rsi,rdx,r10,r8 和 r9

你用 c 写个 printf 的程序看下汇编就懂了。
chanchancl
2020-09-16 14:59:05 +08:00
@katsusan @Mohanson 多谢各位的解答,原来调用普通函数和系统调用的传参顺序也不一样

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/707219

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX