是什么阻止了汇编程序使操作系统崩溃?

电器工程 中央处理器 集会 登记 操作系统
2022-01-27 15:12:39

首先,我是初学者,所以如果这个问题听起来很傻,请指出不正确的假设。

据我了解,操作系统的工作是管理操作系统上运行的硬件和软件。另外,据我了解,汇编程序几乎可以直接控制硬件。在汇编程序中,可以将数据读写到寄存器中,也可以将数据读写到 RAM 中。

鉴于这种随意弄乱寄存器和 RAM 的自由,汇编程序就不可能影响操作系统吗?假设一个操作系统使用寄存器 A 来存储关键信息,并假设我在该操作系统上运行一个组装程序。如果程序成功将垃圾写入寄存器A,操作系统肯定会受到影响。

问题:

  1. 是否可以以上述方式弄乱寄存器A?

  2. 如果不是,是什么阻止了汇编程序修改操作系统使用的寄存器?

4个回答

最后,所有程序都是机器代码,无论源语言是汇编语言还是高级语言。

重要的是,存在限制给定进程可以做什么的硬件机制,包括“弄乱”可能影响其他程序或操作系统本身的寄存器。

这始于“用户”和“主管”操作模式之间的简单区分,后来演变为具有多个“环”权限的安全架构。


这是一个非常通用的示例,可以使其更加具体:

  • 在“用户模式”下,进程无法访问尚未分配给其进程 ID 的内存。分配给其他进程和操作系统本身的内存被阻塞。这包括那些其他进程使用的寄存器的值。这是由 MMU 硬件强制执行的。

  • 因此,在“用户模式”下,进程无法访问 MMU 控制寄存器。

  • 很明显,在“用户模式”下,进程不能将模式更改为“管理员模式”,除非通过一个非常明确的机制来调用操作系统函数。

如果进程试图破坏这些规则中的任何一个,操作系统就会获得控制权。一旦发生这种情况,操作系统可以简单地停止有问题的进程,不再执行它的任何指令。

许多多任务操作系统使用称为进程控制块(PCB) 的数据结构来处理寄存器覆盖问题。当您运行代码时,操作系统会创建一个新进程来跟踪它。PCB 包含有关您的进程和分配用于保存寄存器内容的空间的信息。假设进程 A 当前正在处理器上运行,而您的代码在进程 B 中。当您运行代码时会发生以下情况:

  1. 进程 A 的状态数据(寄存器内容、程序计数器等)被复制到其 PCB 中。

  2. 进程 B 的状态数据从其 PCB 复制到 CPU 寄存器中

  3. 进程 B 在处理器上运行,直到它完成或被抢占

  4. 进程 B 的状态数据被复制回其 PCB

  5. 进程 A 的状态数据被复制回 CPU 并继续运行

如果操作系统作为进程 A 运行,那么您可以看到如何在程序运行之前保存其寄存器,然后在程序结束后将它们复制回 CPU 以防止用户程序与其他进程中发生的事情发生冲突。

为了避免用户进程覆盖内存中的操作系统数据,大多数平台都使用内存分段。基本上,使用虚拟内存,进程看到的地址空间可以映射到任意范围的物理地址。只要进程的物理内存空间不重叠,一个进程就不可能覆盖另一个进程的数据。

当然,不同的操作系统做事不同,所以这并不适用于所有情况。此外,在大多数平台上,操作系统进程以与用户进程不同的模式运行,并且存在一些复杂性。

看你说的是什么平台。

  • 在更基本的处理器上,处理器只执行程序告诉它执行的任何指令。

  • 在更复杂的处理器上,有(至少)两种模式。在一种模式下,处理器执行程序要求它执行的任何操作。在另一种模式下,处理器本身拒绝执行某些指令。

是什么阻止了程序使整个系统崩溃?对于第一种类型的处理器,答案是“没有”。使用基本处理器,单个流氓程序确实可以使整个系统崩溃。所有早期的 8 位家用计算机以及许多 16 位计算机都属于这一类。

在现代 PC 上,处理器具有“保护”硬件。基本上,操作系统运行在允许它做任何事情的特殊模式下,而普通程序运行在处理器只允许某些操作的模式下(基于操作系统在处理器上配置的设置)。诸如仅访问某些寄存器或仅访问特定内存范围之类的东西。

显然,允许单个流氓程序使整个系统崩溃是不好的。(让流氓程序访问它想要的任何数据也存在严重的安全隐患。)为了避免这种情况,您需要做两件事:

  1. 实际上具有保护硬件的处理器(即,它可以被配置为拒绝执行某些指令)。

  2. 一个实际使用这些设施来保护自己的操作系统。(如果操作系统从不使用带有保护电路的芯片,那就不好了!)

几乎任何您可以命名的现代桌面操作系统(Windows、Linux、Mac OS、BSD...)它都是运行在带有保护硬件的处理器上的保护模式操作系统。如果您在某些 8 位微控制器上进行嵌入式开发,那可能没有任何保护硬件。(或任何操作系统,就此而言......)

问:是什么阻止了汇编程序使操作系统崩溃?

A. 什么都没有。

然而,多年来,许多非常聪明的程序员都非常努力地让它变得越来越困难。不幸的是,对于每个聪明的程序员来说,他们之间还有很多很多其他人更有创造力,更有野心,有时甚至比聪明的程序员更幸运。每当一个聪明的程序员说没有人应该、不会或不能做某事时,总会有人找到方法去做。Microsoft Windows(例如)已经存在了将近 35 年,我们仍然有 BSoD(蓝屏死机),这只是导致操作系统崩溃的指令。

让我们从一些术语开始。在计算机上运行的所有东西都以机器代码执行。读取击键或鼠标指针移动的位,更改显示器上像素颜色或从文件中读取字节的位以及计算您的子弹是否击中坏人或决定的位如果您的信用卡申请将被接受,所有这些都将作为一系列机器代码指令执行。有些工作很常见,而且经常完成,因此汇编完成这些工作所需的指令并让每个人都使用该汇编是有意义的。这些允许或帮助他人使用计算机的工作往往被称为操作系统,但它们与任何其他程序之间并没有本质上的不同。它们都只是机器代码指令的序列。

使操作系统更复杂(因此容易崩溃)的原因是它们必须考虑您通常不必考虑的事情。以最简单的工作为例。我想在文件末尾写一条消息。在高级语言中,您会编写如下内容:

  with open("myFile.txt", "w+") as f:
      # do some really clever things
      f.write("Goodbye cruel world!")

让我们忽略有关如何访问和更改物理状态或如何将它们解释为位和字节或如何将这些字节传输到内存和 CPU 的所有细节,并相信所有这些都是由操作系统提供的程序处理的在幕后。让我们想想如何附加到文件的末尾。1)找出文件的结尾在哪里,2)在那个位置写一些东西。什么可能出错?实际上,相当多。当你在做一些聪明的事情时,想想电脑上还发生了什么。如果其他人(包括操作系统本身)所做的任何其他事情以任何方式更改了您正在处理的文件,那么这个非常简单的工作突然变得更加复杂。文件更长,文件更短。该文件不再存在。磁盘已满,