是什么使汇编程序停止崩溃?[关闭]


18

首先,我是一个初学者,所以如果这个问题听起来很愚蠢,请指出错误的假设。

据我了解,操作系统的工作是管理在OS上运行的硬件和软件。而且,据我了解,汇编程序允许人们几乎直接控制硬件。在汇编程序中,可以将数据读取和写入寄存器,以及将数据读取和写入RAM。

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

问题:

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

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


13
聪明的程序员……
Tony Stewart Sunnyskyguy EE75,19年

现在和过去有很多计算机体系结构,并且开发了许多操作系统。您到底指的是什么架构/ OS?在某些(旧)体系结构上,启动后无法停止程序运行,这是正确的。但是现代硬件/ OS内置了硬件工具,这些工具仅以“正常”模式(不是超级用户)为程序提供部分内存,并且无法访问超出此限制的内存。寄存器是免费使用的,因为OS不会在寄存器中存储任何有用的信息,而只是在内存/磁盘上。
Cyclone125 '19

2
在微处理器中,程序在“用户模式”下运行,操作系统在“系统模式”下运行。例如,如果用户模式程序执行了暂停指令,则机器不会停止。暂停将被捕获,并调用操作系统。关于RAM,操作系统需要建立一个环境,为用户模式程序,以便通过内存管理硬件,什么用户程序认为的RAM地址X不会真的是RAM地址X
乔治白

1
@flux我已经更新了我的评论。答案将是:您的问题没有“通用”答案,因为存在/具有不同的计算机体系结构/操作系统。它可以以不同的方式。
Cyclone125

2
...很久以前,我曾经用原始机器代码编写过。是的!:-)
罗素·麦克马洪

Answers:


33

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

重要的是,存在一些硬件机制会限制给定进程可以执行的操作,其中包括可能会影响其他程序或操作系统本身的“与”发送消息的寄存器。

它以“用户”和“主管”操作模式之间的简单区别开始,此后演变为具有多个“权限环”的安全体系结构。


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

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

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

  • 显然,在“用户模式”下,除非通过非常明确定义的机制(包括调用操作系统功能),否则进程无法将模式更改为“管理员模式”。

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


2
如果我理解正确,那么您的意思是:有些处理器具有“用户模式”和“主管模式”。该操作系统以“主管模式”运行,并将处理器置于“用户模式”以运行我的虚构汇编程序。在“用户模式”下,由于硬件的精心设计,汇编程序无法访问寄存器和RAM地址。
Flux

3
基本上,此答案描述了具有MMU和保护模式的现代“类似于i386”的体系结构。但实际上,有许多旧的(i8080,MOS 6502等)以及现代的较简单的(AVR,ARM Cortex-M等)架构都没有这些功能,并且如果使用了某种操作系统(例如,旧的CP / M,现代的FreeRTOS,ChibiOS等),没有什么可以阻止该程序的运行。
Cyclone125

2
@Flux i386(及更高版本)体系结构提供了详细的知识。x86体系结构不仅具有可以保护的内存地址,而且还具有I / O地址。(内存访问与I / O访问使用了不同的指令。)i386 +中有三个内存地址。基于分段/选择器的地址使用选择器寄存器,该选择器寄存器引用表条目(GDT或LDT)将映射对映射到单个32位线性地址。然后,分页表将32位线性地址转换为36位物理地址(P-II)。在两个转换步骤中都存在保护。
jonk

4
@flux您的总结是正确的。具有合适的多任务OS的受保护的内存系统中的程序不应使用任何指令流使系统崩溃。即使是无效的-最终也会由特殊处理程序处理。
pjc50

即使有多个环(至少在x86中),实际使用两个以上的环非常少见。

10

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

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

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

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

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

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

如果操作系统以进程A的身份运行,那么您可以看到如何在程序运行之前保存其寄存器,然后在程序结束后将其复制回CPU,从而防止用户程序与其他进程的混乱。

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

当然,不同的OS会做不同的事情,因此这并非在每种情况下都适用。此外,在大多数平台上,OS进程与用户进程的运行方式不同,并且存在一些复杂性。


4

取决于您正在谈论的平台。

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

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

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

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

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

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

  2. 一个实际上使用这些功能进行自我保护的操作系统。(如果操作系统从不使用带有保护电路的芯片,那就不好了!)

几乎可以命名为任何现代台式机操作系统(Windows,Linux,Mac OS,BSD ...),它是在带有保护硬件的处理器上运行的保护模式操作系统。如果要在某些8位微控制器上进行嵌入式开发,则可能没有任何保护硬件。(或者任何操作系统,对此...)


1

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

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)在该位置写一些东西。可能出什么问题了?其实很多。考虑一下您在做聪明的事情时计算机上还发生了什么。如果其他任何人(包括操作系统本身)所做的任何事情以任何方式更改了您正在处理的文件,那么这项真正简单的工作突然变得复杂得多。文件越长,文件越短。该文件不再存在。磁盘已满,

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.