我知道进程在用户模式和内核模式之间切换以运行。我感到困惑的是,对于每一行代码,我们都可能需要内核。下面是一个例子,我可以解释内核在执行以下代码行中的作用吗。以下内容实际上需要内核模式吗。
如果(a<0(a++
我很困惑,对于每一行代码,我们都可能需要内核。
用户空间中的大多数代码都是在不涉及内核的情况下执行的。当:时,内核被卷入(CPU从用户空间切换到内核(
a( 用户空间代码明确地要求内核做一些事情(调用系统调用(。
b( 有一个IRQ(来自设备(会中断用户空间代码。
c( 内核提供了一些用户空间代码不知道的功能。最常见的原因是虚拟内存管理;但调试和分析是其他原因。
d( 异步通知(例如,导致切换到内核,以便内核可以将程序重定向到合适的信号处理程序(。
e( 用户空间代码做了一些非法的事情(崩溃(。
以下内容实际上需要内核模式吗。
该代码(if(a < 0) a++;
(可能不需要内核的帮助;但也有可能。例如,如果变量a
在先前发送到交换空间的内存中,那么任何访问a
的尝试都是对内核从交换空间获取该数据的请求。以类似的方式,如果可执行文件是内存映射的,但尚未加载(这是改善程序启动时间的常见优化(,那么尝试执行任何指令(无论指令是什么(都可能要求内核从磁盘上的可执行文件中获取代码。
简短回答:这取决于你要做什么,下面的代码取决于环境和编译方式,不需要使用内核。CPU直接执行机器代码,仅在syscall
等指令或页面故障或中断等故障时捕获到内核。
ISA的设计使得内核可以以一种阻止用户空间接管机器的方式设置页表,即使CPU直接获取其机器代码的字节数。这就是当用户空间代码只对自己的数据进行操作时,用户空间代码可以同样高效地运行,进行纯计算而不是硬件访问。
长答案:比较某个东西和增加某个东西的价值不应该需要使用内核,在x86(64位(架构上,以下内容可以这样表示(在NASM语法中(:
; a is in RAX, perhaps a return value from some earlier function
cmp rax, 0 ; if (a<0) implemented as
jnl no_increase ; a jump over the inc if a is Not Less-than 0
inc rax
no_increase:
实际的编译器是无分支的,使用各种技巧,正如您在Godbolt编译器资源管理器上看到的那样。
显然没有任何系统调用,所以这段代码可以在任何x86设备上运行,但没有意义需要内核的是系统调用,现在系统调用不需要有一个可以输出东西的设备。理论上,你可以通过找到一个与视频内存相对应的内存位置来输出东西,你可以操纵像素在屏幕上输出东西,但对于用户来说,这是不可能的,因为虚拟内存。
用户空间应用程序需要一个内核才能存在。如果内核不存在,那么用户空间就不存在:(请注意,并不是每个内核都是用户空间。
所以只做一些类似的事情:
write(open(stdout, _O_RDWR), "windows sucks linux rocks", 24);
显然需要一个内核。
写入/读取任意内存位置(例如:0xB8000(以操作视频内存不需要内核。
TL:DR;例如,您提供的代码,它需要一个内核在用户空间中,但可以在用户空间和内核根本不存在的系统中编写,并且工作非常好(例如:微控制器(
简单地说:它不需要内核工作,因为它不使用任何系统调用,但为了在现代操作系统中进行有意义的操作,它至少需要退出系统调用才能退出并返回代码,否则即使您没有进行动态分配,您也会看到Segmentation错误。
无论我们写什么代码,在用户模式领域都是显而易见的。。内核模式只有在编写执行任何系统调用的代码时才会出现。。
并且由于CCD_ 5没有调用任何系统函数,所以它不会处于内核模式。