- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
据我所知,用户可以拥有一个进程,每个进程都有一个地址空间(其中包含有效的内存位置,该进程可以引用)。我知道进程可以调用系统调用并向其传递参数,就像任何其他库函数一样。这似乎表明所有系统调用都通过共享内存等方式位于进程地址空间中。但也许,这只是一个幻觉,因为在高级编程语言中,系统调用看起来像任何其他函数,当一个进程调用它。
但是,现在让我更深入地分析一下幕后发生的事情。编译器如何编译系统调用?它可能会将进程提供的系统调用名称和参数推送到堆栈中,然后放入“TRAP”之类的汇编指令 - 基本上是调用软件中断的汇编指令。
该 TRAP 汇编指令由硬件执行,首先将模式位从用户切换到内核,然后将代码指针设置为中断服务例程的开始。从此时起,ISR 在内核模式下执行,从堆栈中获取参数(这是可能的,因为内核可以访问任何内存位置,甚至是用户进程拥有的内存位置)并执行系统调用并在end 放弃 CPU,这再次切换模式位,用户进程从停止的地方开始。
我的理解正确吗?
附上我的理解的粗略图:
最佳答案
你的理解非常接近;诀窍在于,大多数编译器永远不会编写系统调用,因为程序调用的函数(例如 getpid(2)
、chdir(2)
等)实际上是提供的通过标准 C 库。标准 C 库包含系统调用的代码,无论是通过 INT 0x80
还是 SYSENTER
调用。如果没有库来进行系统调用,这将是一个奇怪的程序。 (尽管perl
提供了一个syscall()
函数可以直接进行系统调用!很疯狂,对吧?)
接下来是内存。操作系统内核有时可以轻松地访问用户进程内存的地址空间。当然,保护模式是不同的,用户提供的数据必须复制到内核的 protected 地址空间中,以防止在系统调用进行时修改用户提供的数据>:
static int do_getname(const char __user *filename, char *page)
{
int retval;
unsigned long len = PATH_MAX;
if (!segment_eq(get_fs(), KERNEL_DS)) {
if ((unsigned long) filename >= TASK_SIZE)
return -EFAULT;
if (TASK_SIZE - (unsigned long) filename < PATH_MAX)
len = TASK_SIZE - (unsigned long) filename;
}
retval = strncpy_from_user(page, filename, len);
if (retval > 0) {
if (retval < len)
return 0;
return -ENAMETOOLONG;
} else if (!retval)
retval = -ENOENT;
return retval;
}
虽然它本身不是系统调用,但它是一个由系统调用函数调用的辅助函数,用于将文件名复制到内核的地址空间中。它检查以确保整个文件名位于用户的数据范围内,调用从用户空间复制字符串的函数,并在返回之前执行一些健全性检查。
get_fs()
和类似的函数是 Linux 的 x86 根的残余。这些函数具有适用于所有架构的工作实现,但名称仍然过时。
所有与段相关的额外工作都是因为内核和用户空间可能共享可用地址空间的某些部分。在 32 位平台上(数字很容易理解),内核通常有 1 GB 的虚拟地址空间,用户进程通常有 3 GB 的虚拟地址空间。
当进程调用内核时,内核将“修复”页表权限以允许其访问整个范围,并获得预填充的好处 TLB entries用于用户提供的内存。巨大的成功。但是当内核必须上下文切换回用户空间时,它必须刷新 TLB 以删除内核地址空间页面上缓存的权限。
但问题在于,1 GB 的虚拟地址空间不足以容纳大型计算机上的所有内核数据结构。维护缓存文件系统和 block 设备驱动程序、网络堆栈以及系统上所有进程的内存映射的元数据可能需要大量数据。
因此可以使用不同的“分割”:用户两个gig,内核两个gig,用户一个gig,内核三个gig,等等。随着内核空间的增加,用户进程的空间会减少。所以有一个4:4
内存分割为用户进程提供 4 GB,为内核提供 4 GB,并且内核必须修改段描述符才能访问用户内存。 TLB 在进入和退出系统调用时会被刷新,这是一个相当显着的速度损失。但它可以让内核维护更大的数据结构。
64 位平台更大的页表和地址范围可能使前面的所有内容看起来很奇怪。无论如何,我当然希望如此。
关于compiler-construction - 系统调用如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6241627/
我在运行 compile test:compile it:compile经常并且...希望将击键次数减少到类似 *:compile 的数量。 .不过,它似乎不起作用。 $ sbt *:compile
有人可以给我这个问题的提示(或整个解决方案!): 在 Clojurescript 项目中,如何自动将编译日期/时间硬编码在符号中,以便在使用应用程序时显示? 谢谢。 最佳答案 有多种解决方案: 使用l
我是 ember.js 框架的新手,使用 ruby on rails 和 ember.debug.js -v 1.10.1(最新版本)。我一直在网上看到 ember 更改了这个最新的补丁,但我不知
我不是 Fortran 程序员(只是短暂的经验),但我需要编译一个部分用 F77 编写的程序。在我之前有人用 Absoft 编译器编译过它,但现在我需要在另一台机器上用 g77 重复这个过程。对于 A
我运行命令 mvn clean package 我得到了上面的错误我的 pom 是: http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0
我有以下问题。 我想在测试编译阶段排除一些.java文件(** / jsfunit / *。java),另一方面,我想在编译阶段包括它们(id我使用tomcat启动tomcat:运行目标) ) 我的p
符合 wikipedia A compiler is a computer program (or set of programs) that transforms source code writt
我想构建项目,但出现如下错误: 无法执行目标 org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile
当我通过右键单击项目名称进行 Maven 安装时,出现以下错误: [INFO] Scanning for projects... [WARNING] [WARNING] Some proble
我是 Maven 的新手,我想将我的应用程序导入到 Maven。和以前一样,我想将我的 ejb 项目中的类引用到我的 war 项目中。我在类中没有错误,但是如果我在我的父项目上安装 maven,那么我
当我将 ASP.NET Web 应用程序部署到生产环境时,我使用配置转换来删除 debug="true"来自 .但是,就在今天,我注意到 web.config 中的另一个部分如下所示:
This question already has answers here: Maven Compilation Error: (use -source 7 or higher to enable
我正在使用 Maven 3.0.5 和 Spring Tool Source 3.2 并安装了 Maven 插件。当我尝试执行“运行方式---> Maven 安装”时,出现以下错误: [INFO] S
我试图用 AngularJS 创建我自己的递归指令,它调用自己以漂亮的 JSON 格式转换 View 中的对象。好吧,首先我使用 ng-include 调用带有模板的脚本,在其中使用 ng-if 验证
可以通过 @suppress annotation使用Google的Closure Compiler在每个文件的基础上禁止显示警告。但是,似乎无法同时抑制多个警告-例如globalThis和check
假设一个拥有 10 到 20 年经验的熟练开发人员从未构建过编译器或模拟器,哪一个会更具挑战性? 你能比较一下会成为障碍的问题吗? 谢谢。 最佳答案 仿真和编译是完全不同的,但由于两者都被认为是“低级
最近发现Vim中有一个命令叫compiler。您可以使用任何常见的编译器(例如,:compiler gcc、:compiler php 等)来调用它,但它似乎没有任何立竿见影的效果。 我在联机帮助页上
我试图从 spring.io 指南中部署最简单的应用程序 Guide 但是我有一些麻烦.. 我做了什么: 创建的项目。 (来自 spring.io 教程) 下载 heroku CLI 在 Intell
每当进行 Maven Build..>clean install 时,我都会遇到此错误。我尝试过使用不同版本的插件并添加 testFailureIgnore 属性,但问题仍然存在。请找到下面的 POM
我有一个 web 应用程序,我尝试使用 maven 进行编译,不幸的是,在执行 mvn clean package 时它不起作用。 stackoverflow 上有很多问题看起来都一样,但没有解决了我
我是一名优秀的程序员,十分优秀!