简单了解一丢丢系统调用~

本文详细介绍了系统调用的概念,它与普通函数调用的不同之处在于,系统调用需要进入内核空间执行。通过示例展示了在Go语言中如何调用系统调用来打开和关闭文件,并提供了相应的汇编代码。文章强调,虽然程序员日常编程中可能感觉不到系统调用,但实际上很多底层操作如文件操作和网络编程都离不开系统调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

系统调用指的是用类似函数调用的方式调用操作系统提供的API。

概念上来说,系统调用和函数调用极为相似,本质上有很大不同。操作系统代码位于内核地址空间,而CPU在执行用户代码时,特权等级很低,无权访问需要最高优先级才能访问的内核地址空间的代码和数据,所以不能通过简单的call指令直接调用操作系统提供的函数,而需用特殊的指令进入操作系统内核完成指定的功能。

用户代码调用操作系统API也不是根据函数名直接调用,而是根据操作系统为每个API提供的一个整型编号来调用,AMD64 Linux平台约定在进行系统调用时使用rax存放系统调用编号,同时约定使用rdi、rsi、rdx、r10、r9、r8来传递前六个系统调用参数。

像最简单的Go向屏幕输出字符串操作,从打开文件、读写文件以及网络编程中创建socket等都使用了系统调用,平时编程中感觉没有用到系统调用,是因为使用的函数库或package将其封装成了函数,编程人员只需直接调用即可。

看下面这个例子:

package mainimport (  "os")func main() {   fd, err := os.Open("./syscall.go")  // 将会使用系统调用打开文件   ......   fd.Close()  // 将会使用系统调用关闭文件}

上述代码中的os.Open()和fd.Close()最终都是通过系统调用进入操作系统内核完成相应功能,如os.Open()最终会执行如下汇编代码通过openat系统调用打开文件:

mov    0x10(%rsp),%rdi  #第1个参数mov    0x18(%rsp),%rsi  #第2个参数mov    0x20(%rsp),%rdx #第3个参数mov    0x28(%rsp),%r10 #第4个参数mov    0x30(%rsp),%r8  #第5个参数mov    0x38(%rsp),%r9  #第6个参数mov    0x8(%rsp),%rax  #系统调用编号 rax = 267,表示调用openat系统调用syscall                           #系统调用指令,进入Linux内核

上述汇编代码首先将6个参数以及openat系统调用的编号267存入相应寄存器,然后通过syscall指令进入内核执行打开文件的功能。

好啦,到这里本文就结束了,喜欢的话就来个三连击吧。

扫码关注公众号,获取更多优质内容。

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

luyaran

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值