Syscall.RawSyscall()和Syscall.Syscall()在Go中的详细信息是什么?

huangapple go评论83阅读模式
英文:

Details of Syscall.RawSyscall() & Syscall.Syscall() in Go?

问题

我现在正在阅读syscall包中的源代码,并遇到了一些问题:

由于我对syscallassembly完全是个新手,所以请毫不犹豫地分享你对它们的任何了解 Syscall.RawSyscall()和Syscall.Syscall()在Go中的详细信息是什么?

首先是关于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

看起来它是用汇编语言编写的(我看不懂),你能解释一下第61-80行发生了什么,并且第76行下面的ok1:部分的含义是什么吗?

我还在http://golang.org/src/pkg/syscall/zsyscall_darwin_amd64.go中找到了一些代码,其中的zsyscall在文件名中是什么意思?

syscallrawsyscall之间有什么区别?

如果我想编写自己的系统调用函数(是的,os包提供了很多选择,但仍然有一些情况它没有涵盖),该如何使用它们?

这么多新手问题,感谢你耐心阅读和回答 Syscall.RawSyscall()和Syscall.Syscall()在Go中的详细信息是什么?

英文:

I'm reading source code in package syscall now, and met some problems:

Since I'm totally a noob of syscall and assembly, so don't hesitate to share anything you know about it Syscall.RawSyscall()和Syscall.Syscall()在Go中的详细信息是什么?

First about func RawSyscall(trap, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno) : what does its parameter trap, a1, a2, a3 & return value r1 r2 means? I've searched documents and site but seems lack of description about this.

Second, since I'm using darwin/amd64 I searched source code and find it here:
http://golang.org/src/pkg/syscall/asm_darwin_amd64.s?h=RawSyscall

Seems it's written by assemble(which I can't understand), can you explain what happened in line 61-80, and what's the meaning of ok1: part under line 76?

I also found some code in http://golang.org/src/pkg/syscall/zsyscall_darwin_amd64.go , what does zsyscall mean in its filename?

What's the difference between syscall & rawsyscall?

How and when to use them if I want to write my own syscall function(Yes, os package gave many choices but there are still some situation it doesn't cover)?

So many noob questions, thanks for your patience to read and answer Syscall.RawSyscall()和Syscall.Syscall()在Go中的详细信息是什么?

答案1

得分: 7

我将与您分享我对简化汇编的知识:

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	// 系统调用入口
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)  // 错误号
75		RET
76	ok1:
77		MOVQ	AX, 40(SP)	// r1
78		MOVQ	DX, 48(SP)	// r2
79		MOVQ	$0, 56(SP)	// 错误号
80		RET
81	
  • 第61行是例程入口点
  • 第76行是一个名为ok1的标签
  • 第71行是一个有条件的跳转到标签ok1

您在每行左侧看到的短名称称为助记符,代表汇编指令:

  • MOVQ表示移动四字(64位数据)。
  • ADDQ是加四字。
  • SYSCALL是显而易见的
  • JCC是有条件跳转(由前一条指令设置的条件标志)
  • RET是返回

在助记符的右侧,您将找到每个指令的参数,这些参数基本上是常量和寄存器。

  • SP是堆栈指针
  • AX是累加器
  • BX是基址寄存器

每个寄存器可以容纳一定量的数据。在64位CPU架构上,我相信每个寄存器实际上是64位。

SyscallRawSyscall之间唯一的区别在于第14行、28行和34行,Syscall将调用runtime·entersyscall(SB)runtime·exitsyscall(SB),而RawSyscall则不会。我认为这意味着Syscall通知运行时它已切换到阻塞的系统调用操作,并且可以将CPU时间让给另一个goroutine/线程,而RawSyscall只会阻塞。

英文:

I'll share my reduced assembly knowledge with you:

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	
  • Line 61 is the routine entry point
  • Line 76 is a label called ok1
  • Line 71 is a conditional jump to label ok1.

The short names you see on every line on the left side are called mnemonics and stand for assembly instructions:

  • MOVQ means Move Quadword (64 bits of data).
  • ADDQ is Add Quadword.
  • SYSCALL is kinda obvious
  • JCC is Jump if Condition (condition flag set by previous instruction)
  • RET is return

On the right side of the mnemonics you'll find each instruction's arguments which are basically constants and registers.

  • SP is the Stack Pointer
  • AX is the Accumulator
  • BX is the Base register

each register can hold a certain amount of data. On 64 bit CPU architectures I believe it's in fact 64 bits per register.

The only difference between Syscall and RawSyscall is on line 14, 28 and 34 where Syscall will call runtime·entersyscall(SB) and runtime·exitsyscall(SB) whereas RawSyscall will not. I assume this means that Syscall notifies the runtime that it's switched to a blocking syscall operations and can yield CPU-time to another goroutine/thread whereas RawSyscall will just block.

huangapple
  • 本文由 发表于 2013年6月7日 14:52:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/16977988.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定