首页 游戏 软件 资讯 排行榜 专题
首页
科技数码
Linux系统调用详解:从原理到实践的完整指南

Linux系统调用详解:从原理到实践的完整指南

热心网友
43
转载
2025-10-30

一说到服务,很多人首先想到的可能是服务器。假设客户端是浏览器,浏览器发送HTTP请求,服务器接收请求后解析并调用相应的handler。从本质上讲,这就是客户端触发了服务器端某个函数的执行,这时我们便说客户端请求了服务器端上的服务。

系统调用与普通的函数调用并无本质区别。普通函数调用通常调用我们编写的函数或其他库函数,而系统调用则是调用了内核中的函数。更学术一点的说法是:所谓系统调用,是指用户态程序请求操作系统提供的服务。

一提到服务,大家最先想到的通常是服务器。假设客户端是浏览器,浏览器发送HTTP请求,服务器接收到请求后进行解析,然后调用相应的handler。本质上,这是客户端触发了服务器端某个函数的运行,此时我们就可以说客户端请求了服务器端上的服务。

而系统调用与此类似,只不过用户态程序并非通过HTTP来触发操作系统中某个函数的执行,而是通过机器指令来实现的。因为用户态的App和操作系统运行在同一台计算机系统中,而客户端和服务器端则运行在不同的计算机系统里(绝大多数情况下),因此客户端只能通过网络协议HTTP与服务器进行通信。

图片图片

更通俗的说法是这样的:所谓系统调用,指的是用户态的某个函数调用内核中的某个函数。

接下来,我们用一段简单的hello world程序来看看系统调用,这段程序需要运行在x86_64架构下:

.section .datamsg: .ascii "Hello, world! " # 字符串定义,包含换行符 len = . - msg # 计算字符串长度(包含换行符).section .text.global _start_start: # 调用 write(1, msg, len) movq $1, %rax # syscall 1 (write) movq $1, %rdi # fd = 1 (stdout) movq $msg, %rsi # 字符串地址 movq $len, %rdx # 字符串长度 syscall # 调用 exit(0) movq $60, %rax # syscall 60 (exit) xorq %rdi, %rdi # status = 0 syscall

使用以下命令编译:

$ gcc -c test.S$ ld -o test test.o

然后执行:

./testHello, world!

这段汇编代码成功地打印出了hello world。那么这段代码具体是什么意思呢?

我们来看.data这一段,这里说的是程序定义了哪些数据,而.text段则包含了程序的执行部分。我们之前提到进程的内存布局时,总是会谈到数据段和代码段,这里的数据段指的就是汇编中的.data段,代码段就是汇编中的.text段。现在你应该明白了吧。

图片图片

在.text段中,我们看到了一条略显奇怪的指令——syscall,这条指令到底是什么意思呢?

我们来查阅一下Intel的开发手册:

SYSCALL invokes an OS system-call handler at privilege level 0. It does so by loading RIP from the IA32_LSTAR MSR (after saving the address of the instruction following SYSCALL into RCX). (The WRMSR instruction ensures that the IA32_LSTAR MSR always contain a canonical address.)

这段话告诉我们,Intel处理器在执行syscall指令时,会在内核态调用操作系统的某个函数,即syscall-call handler。那么CPU是如何知道某个syscall-call handler在内存中的地址呢?

原来,syscall-call handler所在的内存地址存储在MSR寄存器中。那么又是谁将这个地址存储在了MSR寄存器中呢?很显然,是操作系统。接下来我们以Linux为例进行说明。

Linux内核在初始化时会将syscall-call handler,也就是Linux内核中entry_SYSCALL_64函数的地址写入MSR寄存器中:

wrmsrl(MSR_LSTAR, entry_SYSCALL_64);

其中,syscall-call handler也就是entry_SYSCALL_64定义在Linux源码中的arch/x86/entry/entry_64.S中。上述初始化MSR寄存器的代码定义在了arch/x86/kernel/cpu/common.c中。

现在我们知道了,当CPU执行syscall时会无条件跳转到MSR寄存器中保存的函数地址,也就是entry_SYSCALL_64函数。那么很显然,所有系统调用的入口都是entry_SYSCALL_64函数。那么操作系统该如何区分到底是调用的read系统调用还是write等系统调用呢?

原来,操作系统中给每种系统调用分配了一个序号,就像Linux中这样:

0common read sys_read1common write sys_write2common open sys_open3common close sys_close4common stat sys_newstat5common fstat sys_newfstat6common lstat sys_newlstat7common poll sys_poll8common lseek sys_lseek9common mmap sys_mmap...

可以看到,0号系统调用表示的是内核中的read函数,1号系统调用表示的是内核中的write函数。在进行系统调用时,会表示系统调用类别的序号写入通用寄存器中。

从上面这个表格可以看到,write系统调用的序号是1,因此在hello world程序中我们将1写入寄存器rax中:

movq $1, %rax

这条指令表示我们将要调用第1号系统调用,也就是sys_write。hello world程序中后续三条机器指令的功能分别是:

# 写入文件描述符1movq $1, %rdi# 保存指向字符串的指针movq $msg, %rsi# 写入数据的大小movq $len, %rdx

实际上,这四条机器指令都是为执行syscall进行的铺垫,即执行syscall所需要的参数。可以看到,我们进行系统调用传递参数时都是通过寄存器来完成的。

这样当CPU执行syscall指令时,就会跳转到Linux内核中的write函数,同时在执行该函数时也能知晓write函数所需要的参数是什么。

来源:https://www.51cto.com/article/828117.html
免责声明: 游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

相关攻略

Linus Torvalds 提醒开发者 AI 再强也需独立思考
业界动态
Linus Torvalds 提醒开发者 AI 再强也需独立思考

在近日举行的北美开源峰会上,Linux创始人林纳斯·托瓦兹分享了一个深刻洞察:人工智能技术正悄然重塑Linux内核开发的节奏与生态。 托瓦兹指出,自Git版本控制系统确立稳定的发布流程以来,Linux内核的迭代周期已平稳运行近二十年。然而,过去半年间,这一长期形成的稳定节奏出现了显著波动。 代码提交

热心网友
05.23
Ubuntu系统安装OpenClaw详细步骤教程
AI资讯
Ubuntu系统安装OpenClaw详细步骤教程

第一步:彻底卸载旧版 Node js 为确保安装过程顺利,避免版本冲突,我们首先需要完全移除系统中可能存在的旧版本 Node js 及其关联组件。 请打开终端,依次执行以下命令: apt remove --purge -y nodejs libnode-dev npm 该命令将彻底卸载 Node j

热心网友
05.20
Linux系统Nginx服务器HTTPS证书安装配置教程
系统平台
Linux系统Nginx服务器HTTPS证书安装配置教程

为Nginx启用HTTPS加密,看似复杂实则核心步骤清晰。关键在于确保Nginx编译时已包含--with-http_ssl_module模块,并正确配置证书与私钥的绝对路径及严格权限(私钥文件权限应为600)。实现HTTPS服务的最小化配置仅需三行指令:listen 443 ssl、ssl_cert

热心网友
05.20
Linux批量重命名文件教程:rename与mv命令详解
系统平台
Linux批量重命名文件教程:rename与mv命令详解

Linux系统批量重命名文件有多种方法。基础方法是使用mv命令配合for循环,适合简单的前缀、后缀修改。C语言版rename命令可进行直接字符串替换。功能更强的Perl版rename支持正则表达式,能实现复杂模式匹配。mmv工具通过通配符映射,适合结构化重命名。无论使用哪种方法,都建议先通过预览模式确认操作,避免误改。

热心网友
05.20
Kubernetes Dashboard安装与配置详细图文教程
系统平台
Kubernetes Dashboard安装与配置详细图文教程

默认部署KubernetesDashboard后服务类型为ClusterIP,无法从外部访问。需将Service类型改为NodePort并指定30000-32767范围内的端口,才能通过浏览器直接访问。登录失败常因缺少权限绑定、token过期或命名空间错误。临时调试可使用port-forward,但生产环境不推荐。部署前需确保集群基础配置正确,避免后续问题。

热心网友
05.20

最新APP

宝宝过生日
宝宝过生日
应用辅助 04-07
台球世界
台球世界
体育竞技 04-07
解绳子
解绳子
休闲益智 04-07
骑兵冲突
骑兵冲突
棋牌策略 04-07
三国真龙传
三国真龙传
角色扮演 04-07

热门推荐

刑事案件电子数据取证密码获取程序拟明确
业界动态
刑事案件电子数据取证密码获取程序拟明确

公安部就电子数据取证规则公开征求意见,拟将网络安全等行政案件纳入适用范围,并规范取证流程与核心概念。新规特别明确了获取密码、调取通讯内容等特殊程序,需经严格审批并保障当事人权利。配套法律文书也同步优化,以构建更规范且注重权利保障的取证体系。

热心网友
05.23
小鹏G9降价12万背后何小鹏的豪赌与挑战
业界动态
小鹏G9降价12万背后何小鹏的豪赌与挑战

理想L9和LIvis的定价策略刚掀起波澜,小鹏GX的最终价格就给出了更猛烈的回应——从近40万元的预售价直降至27万元起。用小鹏产品矩阵负责人吴安飞的话说,这叫“9系的产品,8系的价格”。 这12万元的下调,效果堪称立竿见影。发布会次日,小鹏集团港股股价一度大涨超8%。更关键的是市场订单:上市12小

热心网友
05.23
魏建军感谢于东来支援环塔拉力赛 红牛千箱胖东来厨师助阵
业界动态
魏建军感谢于东来支援环塔拉力赛 红牛千箱胖东来厨师助阵

5月21日,环塔拉力赛新疆且末赛段大营迎来了一位备受瞩目的访客——知名零售企业胖东来的创始人于东来。他专程前往长城汽车车队营地,与参赛车手及后勤团队进行了深度交流。据悉,于东来此次自驾越野之旅已历时一月,随行车队中包含多款国产越野车型。经过实地驾驶与多维度对比,他对以长城汽车为代表的国产越野车品质给

热心网友
05.23
2026年比特币官方APP下载入口及官网安全访问指南
web3.0
2026年比特币官方APP下载入口及官网安全访问指南

比特币官方入口在哪里?一个核心门户的权威指南 说起比特币,很多人第一反应是去找它的“官网”或“官方App”。但这里有个关键点需要先理清:比特币本质上是一种去中心化的全球数字货币,它不属于任何一家公司或机构,而是由一个庞大的、遍布全球的社区共同维护。因此,它并没有传统意义上由某个企业运营的“官方网站”

热心网友
05.23
蚂蚁开源万亿参数思考模型Ring-2.5-1T详解
AI资讯
蚂蚁开源万亿参数思考模型Ring-2.5-1T详解

Ring-2 5-1T是什么 在当今大模型技术激烈竞争的赛道上,追求更长的上下文处理能力和更强大的深度推理性能已成为核心焦点。近日,蚂蚁集团旗下的inclusionAI团队重磅开源了Ring-2 5-1T模型,这是一个参数规模高达万亿级别的混合线性思考大语言模型。该模型基于先进的Ling 2 5架构

热心网友
05.23