The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
chanchancl

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

  •  
  •   chanchancl · Sep 15, 2020 · 2507 views
    This topic created in 2081 days ago, the information mentioned may be changed or developed.

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

    EDI, ESI, EDX, ECX, R8, R9

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

    请问有什么原因吗

    5 replies    2020-09-16 14:59:05 +08:00
    chanchancl
        1
    chanchancl  
    OP
       Sep 15, 2020
    比较了一下,发现我手里的 go1.15.1 的源码,和连接里的 go1.15.2 的代码又不一样了。。。
    这些寄存器里到底哪些是传参的。。哪些是作为共享用的呢?
    chanchancl
        2
    chanchancl  
    OP
       Sep 15, 2020
    以 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
        3
    katsusan  
       Sep 15, 2020
    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
        4
    Mohanson  
       Sep 16, 2020 via Android
    用户模式调用约定( calling convention ) 是 EDI, ESI, EDX, ECX, R8, R9

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

    你用 c 写个 printf 的程序看下汇编就懂了。
    chanchancl
        5
    chanchancl  
    OP
       Sep 16, 2020
    @katsusan @Mohanson 多谢各位的解答,原来调用普通函数和系统调用的传参顺序也不一样
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1143 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 23:11 · PVG 07:11 · LAX 16:11 · JFK 19:11
    ♥ Do have faith in what you're doing.