我正在阅读 syscall
包中的源代码,遇到了一些问题:
因为我对syscall
和assembly
完全是个菜鸟,所以不要犹豫,分享你所知道的一切:)
首先关于 func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
:它的参数是什么 trap, a1, a2, a3
& 返回值 r1 r2
是什么意思?我已经搜索过文档和站点,但似乎缺乏关于此的描述。
其次,因为我使用的是 darwin/amd64
,所以我搜索了源代码并在此处找到它:
http://golang.org/src/pkg/syscall/asm_darwin_amd64.s?h=RawSyscall
好像是用assemble写的(看不懂),能解释一下第61-80行发生了什么吗,第76行下面的ok1:
部分是什么意思?
我还在 http://golang.org/src/pkg/syscall/zsyscall_darwin_amd64.go 中找到了一些代码, zsyscall
在文件名中是什么意思?
syscall
和 rawsyscall
有什么区别?
如果我想编写自己的系统调用函数(是的,os 包提供了很多选择,但仍有一些情况它没有涵盖),如何以及何时使用它们?
这么多菜鸟问题,感谢您的耐心阅读和回答:)
最佳答案
我将与您分享我简化的 assembly 知识:
61 TEXT ·RawSyscall(SB),7,$0
62 MOVQ 16(SP), DI
63 MOVQ 24(SP), SI
64 MOVQ 32(SP), DX
65 MOVQ $0, R10
66 MOVQ $0, R8
67 MOVQ $0, R9
68 MOVQ 8(SP), AX // syscall entry
69 ADDQ $0x2000000, AX
70 SYSCALL
71 JCC ok1
72 MOVQ $-1, 40(SP) // r1
73 MOVQ $0, 48(SP) // r2
74 MOVQ AX, 56(SP) // errno
75 RET
76 ok1:
77 MOVQ AX, 40(SP) // r1
78 MOVQ DX, 48(SP) // r2
79 MOVQ $0, 56(SP) // errno
80 RET
81
- 第61行是例程的入口
- 第76行是一个名为
ok1
的标签 - 第 71 行是条件跳转到标签
ok1
。
您在左侧每一行看到的短名称称为助记符
,代表汇编指令:
MOVQ
表示移动四字(64 位数据)。ADDQ
是添加四字。SYSCALL
有点明显JCC
is Jump if Condition (condition flag set by previous instruction)RET
是返回
在助记符的右侧,您会发现每条指令的参数,它们基本上是常量和registers。 .
SP
是堆栈指针AX
是累加器BX
是基址寄存器
每个寄存器可以保存一定数量的数据。在 64 位 CPU 架构上,我相信它实际上是每个寄存器 64 位。
Syscall
和 RawSyscall
之间的唯一区别在于第 14、28 和 34 行,其中 Syscall
将调用 runtime·entersyscall( SB)
和 runtime·exitsyscall(SB)
而 RawSyscall
不会。我认为这意味着 Syscall
通知运行时它已切换到阻塞系统调用操作,并且可以将 CPU 时间交给另一个 goroutine/线程,而 RawSyscall
只会阻塞。
关于unix - Go 中 Syscall.RawSyscall() 和 Syscall.Syscall() 的详细信息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16977988/