【问题标题】:How processor handles case of division by zero处理器如何处理被零除的情况
【发布时间】:2014-07-15 17:10:48
【问题描述】:

很好奇处理器/CPU 在执行除以零指令时一般会做什么,或者说,在英特尔 cpu 和 Linux 上。还有如何将错误转发给应用程序,以便它可以记录错误或通知开发人员?

谢谢!

【问题讨论】:

  • 哪个处理器?哪个操作系统?
  • @OliCharlesworth 啊,刚刚编辑了问题。基本上,我只是想大致了解整个过程是如何工作的。我们可以假设它是 intel cpu 上的 linux。

标签: operating-system signals cpu interrupt interrupt-handling


【解决方案1】:

笼统地回答,而不是深入探讨 x86_64 上的 Linux 的血淋淋的细节,这可能会混淆概念。

CPU 倾向于抛出异常中断,例如被零除或取消引用 NULL 指针。这些中断被捕获,就像硬件中断一样,停止当前程序的执行并将控制权返回给操作系统,然后由操作系统处理事件。虽然这些操作非常依赖于环境,但通常可能会终止程序,释放所有资源(内存、打开的文件),并且可以选择为开发人员系统上的调试目的生成核心转储/堆栈跟踪。

运行时可能能够配置一些东西,因此调用异常处理程序,也许脚本语言想要捕获整数除以 0,或整数溢出,然后抛出编程语言异常或生成诊断信息以帮助程序员了解在哪里 &为什么,它发生了。引发信号,可能会被应用程序捕获并处理,或者导致终止,是另一种传统的可能性。

在某些 RISC CPU 上,操作系统中的软件陷阱会运行以修复未对齐的数据访问,因此可以读取内存,但会降低性能。过去,陷阱有时会用于模拟已定义的指令,但特定 CPU 模型并未在硬件中实现这些指令。我还看到记录了硬件内存错误,因为操作系统启动了 ECC 内存恢复操作,但在 x86 上的处理方式不同。

系统调用实际上使用相同的机制从用户空间应用程序跳转到操作系统内核,然后处理事件,因此常用术语trap。

【讨论】:

  • 对,试图将它们与外围设备产生的中断区分开来,快速解释可能很棘手
  • @Rob11311 "这些中断被捕获,比如硬件中断,停止当前程序的执行并将控制权返回给操作系统",所以这些都是由cpu处理的,即由硬件或固件实现(因为此时操作系统无法控制),对吧?
  • 是的,是硬件。即使没有其他中断发生(外设或系统调用),OS 调度程序也可以通过调度定时器中断来重新获得控制权,因此实际上它只是将 CPU 借给用户程序。
【解决方案2】:

让我试着用不同的方式回答这个问题。我使用过的每个处理器都定义了一个中断向量结构。在 Intel 芯片上,这种结构称为中断调度表 (IDT)。中断向量是一个指向函数的指针数组。数组中的每个条目对应一个特定事件(中断或异常(故障或陷阱))。

操作系统为每个事件设置函数(中断处理程序、异常处理程序)。当发生除以零时,会触发异常。 CPU 通过调用对应于被零除的中断向量中的异常处理程序来响应。在 Pentium 上,这是表中的第一个条目。

【讨论】:

    【解决方案3】:

    当“在 CPU 中”发生 DIV0 错误时,应用程序将无法记录任何内容(除非某些子进程正在管理)。

    在 CPU 中几乎不会发生 DIV0,它会被以下方法捕获:

    $  echo $(( 1/0 ))
    bash: 1/0 : division by 0 (error token is "0 ")
    

    这不是证据 - 可能是日志。但它以bash: 开头,并意识到违规令牌"0 " 中的空间。

    在 Pentium 上,这是表中的第一个条目。

    User33 用这个结束了他的严格描述。由于调度程序问题,我来到这里,我使用 CPU 中的 DIV0 示例来说明该进程的(突然)“阻塞”(更好:停止)。我的观点是:CPU 遵循传统和逻辑,拒绝除以零,包括任何廉价的黑客攻击。根据定义,它是一个句号。不应该发生,但如果,则不会处理进一步的指令。相反,使用了非常特殊的第一个条目。特殊,因为这是 CPU 引发“无法继续”异常的最简单情况。

    在没有保护模式的情况下,cpu 中的 div0 是系统崩溃。但是由于这些特殊的隐藏表和函数,在保护模式下,内核/调度程序可以重新启动 CPU 并继续进行,而不会停止进程。该进程已死,将被删除 - 必须启动另一个进程,就像第一个进程一样;)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-30
      相关资源
      最近更新 更多