这段设置五个控制寄存器位为1的汇编代码会不会损坏我的处理器?

14
一个朋友给我发了这段代码,并声称它可能会损坏处理器。这是真的吗?
void damage_processor() {
    while (true) {
        // Assembly code that sets the five control registers bits to ones which causes a bunch of exceptions in the system and then damages the processor
        Asm(
            "mov cr0, 0xffffffff \n\t"
            "mov cr1, 0xffffffff \n\t"
            "mov cr2, 0xffffffff \n\t"
            "mov cr3, 0xffffffff \n\t"
            "mov cr4, 0xffffffff \n\t"
        )
    }
}

这是真的吗?

6
有趣。如果能编写直接破坏处理器的代码,我会感到震惊,但是从应用程序中创建导致系统不稳定,并在重启前导致完全系统崩溃的情况肯定是可能的。 - Nathan Taylor
16
不,这不是真的,但它会让你的显示器炸裂。 - Attila Kun
8
你试过了吗? - Christoffer
13
大家都知道HCF是一条指令,会摧毁你的计算机。http://zh.wikipedia.org/wiki/Halt_and_Catch_Fire - i_am_jorf
10
我听说运行这段代码会让你在StackOverflow上获得+1000的声望值。 - William Leara
显示剩余5条评论
8个回答

19

从用户空间代码吗?不可以。这会导致特权异常,内核会终止您的程序。从内核代码呢?我怀疑;您将会抛出异常,并且必须手动设置故障处理程序以返回到相关代码以继续执行。如果 CR3 的一部分移动成功,则您也很可能会造成三重错误,因为它控制页面表地址,而您可能会在指令获取、处理器获取和双倍故障处理程序获取时引发故障。如果发生这种情况,CPU 应该会关闭。

请查阅英特尔或 AMD 系统编程手册,它们将告诉您在写入无效位到控制寄存器时会抛出哪些异常。


3
三重故障通常会触发重新启动。 - myron-semack
2
双重错误处理程序的获取应该始终来自任务门,带有CPU加载的“安全”CR3值以及安全堆栈和寄存器值。破坏CR3“理论上”不会导致系统三重故障,但这仍然不是一个好主意。 - Matthew Iselin

16

如果您让它运行约20年,也许会如此。


11

也许这段代码会导致你的处理器/系统崩溃,但它不可能永久损坏它。

想象一下如果真是这样:病毒/木马会立即利用它攻击计算机或在检测后隐藏它们的活动。

即使有任何代码可以损坏处理器,处理器制造商也可以发布所谓的微代码更新,这类似于处理器的软件修复。这些微代码更新由操作系统和/或BIOS(和处理器制造商)提供,并在执行此类代码之前加载到处理器中。

总之:不,你的朋友是错误的,假设我们谈论的是x86 / x64平台。


5

不会的,如果目的是为了疯狂地锻炼处理器以期望让它崩溃,则计算机系统有散热解决方案(风扇、铜制换热器、散热器等)来防止过热。如果散热方案出现故障,BIOS将断言#THERMTRIP并关闭机器。


2
这个甚至无法组装;mov到控制寄存器的源操作数必须是GPR,而不是立即数或内存。 (https://www.felixcloutier.com/x86/mov-1)。它也无法编译;在GNU C中,关键字是asm()而不是Asm()
所以,不,这段代码无法执行任何操作,因为它无法编码成机器码,所以对于x86 CPU来说没有任何可执行的内容。
另外,CR1是保留的mov cr1, eax(32位模式)或mov cr1, rax(64位模式)将导致#UD非法指令错误。
CR3是顶级页表指针,因此设置它很可能会导致代码获取从其他地方开始,除非物理地址0xFFFFF000处的页面是一个有用的顶级页目录,其中包含当前RIP或EIP的映射。(在64位模式下是PML4,在PAE模式下称为其他名称。)对其他控制寄存器的写操作将启用PAE,如果我们处于传统模式下,那么最好已经启用了它,因为同一个页面既作为32位2级表的传统页目录,又作为顶级PAE表的可能性更小。(低12位要么被忽略,要么是PCID = 进程上下文ID。) 发送给您这段代码的人只是在胡编乱造。这甚至不能作为使用临时寄存器存储值“-1”的伪代码。
如果我们删除CR1写入并编写真正使用临时寄存器的代码,以便它能够真正执行,即使在内核模式下运行,也不会损坏您的硬件。例如:mov rax, -1 / mov cr0, rax / .... 或者为了更好地匹配代码,我猜他们可能会使用mov eax, -1 / mov cr0, rax 来零扩展那些32位的零。(64位模式只能对控制寄存器执行64位的mov操作。传统的32位模式只能对它们执行32位的mov操作。)
这可能会导致您的计算机崩溃并强制重新启动。(或者通过三次故障直接导致重新启动,如果它到达设置CR3的部分,即顶级页表,将其设置为全1,如果那不是有效的物理地址或该页不是有用的顶级页表。)
如果CR3的新值指向一个页表,使得CS:RIP仍然指向下一条指令,那么对CR4的写操作肯定会引发一个#GP(0)异常,正如Intel的手册中所记录的那样,适用于保护模式或64位模式。

保护模式异常 ¶

#GP(0) (通用保护错误):
  • 如果当前特权级不为0(也就是需要内核模式)。
  • 如果尝试在CR0中写入无效的位组合(例如当PE标志设置为0时将PG标志设置为1,或者将NW标志设置为1时将CD标志设置为0)。
  • 如果尝试在CR4的任何保留位上写入1。
  • 如果尝试将1写入CR4.PCIDE。(在64位模式下是可以的,但在传统保护模式下不行)。
  • 如果在页目录指针表(PDPT)中设置了任何保留位,并且加载控制寄存器导致PDPT被加载到处理器中。
#UD (非法指令异常):
  • 如果使用了LOCK前缀。
  • 如果尝试访问CR1、CR5、CR6、CR7或CR9-CR15。
写入CR0可能不会出错;设置所有位可能不是无效的组合。这段代码不值得再花更多的精力证明它是无意义的。

1

我听说 Pentium I 存在一个 bug,当在紧密循环中给出一系列无意义的指令时,会烧毁一个单翻转门,以至于热保护无法保护它。

我曾经找到过一次参考资料,旧的 CPU 在实模式下这样做可能会被烧坏:

halt:
    jmp short halt

正确的代码是

halt:
    nop
    jmp short halt

4
你能否为我们提供参考文献? - Kosi2801
2
我真的很怀疑。据我所知,Pentium 1没有热保护。此外,任何经过Intel批准的散热器都足以在最大功率下保持核心温度稳定。http://www.intel.com/design/pentium/datashts/24199710.pdf - myron-semack
2
正确的8086代码以空转停止,可以使处理器冷却,相比于运行一个空循环,是halt: \ hlt \ jmp halt - undefined
@ecm:是的,是的,就是这样。在386中,这并没有节省任何电力。 - undefined

1

抱歉,该代码无法在ARM处理器上运行。

在许多处理器中,设置状态字或影响处理器的指令仅限于“监管员”模式。良好的操作系统在“受保护”的模式下运行用户代码,该模式不具有“监管员”模式的相同功能。在用户模式下执行现代处理器上的特权指令会生成异常。

您和您的朋友可以随时查阅汇编语言参考手册上的指令并验证其操作。


0

这段代码可能只会导致机器重新启动。根据我的经验,执行软件代码可能会使x86 CPU变砖。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接