如果内核控制了系统,汇编语言如何工作?
汇编语言被引入作为计算机“理解”的助记符和各种宏的集合,以使某些任务更容易。
如果汇编程序不向操作系统发出请求就无法控制 CPU 和内存,它如何控制 CPU 和内存?
例如,如果我想做指令mov ax, #4
,我是否需要我的程序向操作系统发送请求才能这样做?
我真的很好奇...
谢谢!
如果内核控制了系统,汇编语言如何工作?
汇编语言被引入作为计算机“理解”的助记符和各种宏的集合,以使某些任务更容易。
如果汇编程序不向操作系统发出请求就无法控制 CPU 和内存,它如何控制 CPU 和内存?
例如,如果我想做指令mov ax, #4
,我是否需要我的程序向操作系统发送请求才能这样做?
我真的很好奇...
谢谢!
CPU 具有协助操作系统保护资源的机制。让我们使用您的 x86 芯片示例。“通用”寄存器,例如eax
,不受保护。但是调试寄存器,例如DR0
,是。
当操作系统运行时,CPU 在“ring 0”或人们称之为“系统模式”的通用术语中执行。这些程序在 x86 上运行“ring 3”,也就是人们所说的“用户模式”。
当执行从 ring 3 变为 ring 0 时(稍后将详细介绍如何完成),CPU 将放弃用户模式的保护。这就是允许操作系统更改调试寄存器的原因。
但是,操作系统保护的主要内容是内存位置和设备输入/输出。出于这个原因,in
andout
指令是特权的,并且可能不会在 ring 3 处执行。
内存通过 TLB 保护,TLB 还用于定义对用户模式进程可见的虚拟内存 (VM) 地址范围。正是这张表控制了每个进程可见的内存空间。TLB 本身存储在内存中,只有 ring 0 操作系统可以修改。类似地,中断向量和任何内存映射设备都分配给只有操作系统可以访问的内存范围。
例如,当您执行时,mov [eax], 3
将在 TLB 中查找 eax 引用的地址。CPU 根据 TLB 中的访问位(例如 NOEXEC 位)确定指令是否合法地访问内存。
当操作系统调度程序交换进程时,通用寄存器eax
将保存在操作系统维护的每个线程内存区域中。切换到的线程从其先前寄存器值的内存映像中恢复。
如果操作系统干扰每条机器指令,计算机会非常慢。特别是,应尽可能快地保持对通用寄存器的访问。内存访问的 TLB 查找被缓存并且不比内存访问本身慢。
To switch from ring 3 to ring 0, a software interrupt is generated. This is the "system call" interrupt. Interrupts run at ring 0, and are configured before the first process begins, by the OS. The system call interrupt transfers control to the OS code. When execution returns from the interrupt service routine, the CPU is returned to ring 3.
您的程序可以运行它想要的任何指令,只要它不访问其ring之外的资源/内存。如果是这样,它将产生一个错误(分段违反或一般保护)并被内核杀死。
汇编语言只是一种编程语言,如 C 或 Pascal 之类的。为了让程序无论是什么语言都能执行,在计算机上运行的程序必须是该计算机的机器代码。许多/大多数语言要么像汇编语言那样被汇编,要么像高级语言那样被编译成目标系统的机器代码。一些语言(Java、Python 和 Pascal)被编译为中间语言,这也是一种机器代码,但随后在运行时由以某种语言编写的程序解释,该程序编译为机器代码。所以这里再次机器代码在机器上运行。
无论您在谈论什么语言,系统调用都是系统调用和内存限制以及其他操作系统施加的限制。因此,无论是 C 语言还是汇编语言,您都可以进行系统调用以打开文件或将一些内容打印到终端或其他任何东西。