【问题标题】:x86 registers: MBR/MDR and instruction registersx86 寄存器:MBR/MDR 和指令寄存器
【发布时间】:2019-01-02 11:28:05
【问题描述】:

根据我的阅读,IA-32 架构有 10 个 32 位和 6 个 16 位寄存器。

32位寄存器如下:

  • 数据寄存器 - EAX、EBX、ECX、EDX
  • 指针寄存器 - EIP、ESP、EBP
  • 索引寄存器 - ESI、EDI
  • 控制寄存器 - EFLAG(EIP 也归类为控制寄存器)

16位寄存器如下:

  • 代码段:包含所有要执行的指令。
  • 数据段:它包含数据、常量和工作区。
  • 堆栈段:它包含过程或子例程的数据和返回地址。
  • 额外段 (ES)。指向额外数据的指针。
  • F 段 (FS)。指向更多额外数据的指针。
  • G 段 (GS)。指向更多额外数据的指针。

但是,我找不到有关当前指令寄存器 (CIR) 或内存缓冲寄存器 (MBR)/内存数据寄存器 (MBR) 的任何信息。这些寄存器是否被称为其他东西?这些寄存器是 32 位的吗?

我假设它们是 32 位的,并且这种架构下最常用的指令长度小于 4 个字节。从观察来看,很多指令似乎都在 4 个字节以下,例如:

  • 推送 EBP (55)
  • MOV EBP、ESP (8B EC)
  • LEA (8D 44 38 02)

对于较长的指令,CPU 将使用前缀代码和其他可选代码。较长的指令需要超过一个周期才能完成,这取决于指令长度。

我是否正确,有问题的寄存器长度为 32 位? IA-32 架构中是否还有其他我应该注意的寄存器?

【问题讨论】:

    标签: x86 cpu cpu-architecture cpu-registers


    【解决方案1】:

    不,您所说的寄存器是现代 x86 CPU 中不作为物理寄存器存在的实现细节。

    x86 没有指定您在玩具/教学 CPU 设计中发现的任何实现细节。 x86 手册仅指定架构上可见的内容。

    英特尔和 AMD 的优化手册详细介绍了内部实现,这与您的建议完全不同。现代 x86 CPU 将架构寄存器重命名为更大的物理寄存器文件,从而实现乱序执行,而不会因写后写或读后写数据危险而停止。 (有关寄存器重命名的更多详细信息,请参阅Why does mulss take only 3 cycles on Haswell, different from Agner's instruction tables?)。请参阅this answer 了解乱序执行的基本介绍,以及实际 Haswell 内核的框图。 (请记住,物理芯片有多个内核)。


    与简单或玩具微架构不同,几乎所有高性能 CPU 都支持未命中和/或未命中命中(多个未完成的缓存未命中,而不是完全阻塞等待第一个完成的内存操作)


    可以构建一个具有单个 MBR / MDR 的简单 x86;如果最初的 8086 和 386 微架构有类似的东西作为内部实现的一部分,我不会感到惊讶。

    但例如,Haswell 或 Skylake 内核每个周期可以从/到 L1d 缓存执行 2 次加载和 1 次存储(请参阅 How can cache be that fast?)。显然他们不能只有一个 MBR。相反,Haswell 有 72 个加载缓冲区条目和 42 个存储缓冲区条目,它们都是内存顺序缓冲区的一部分,它支持加载/存储的乱序执行,同时保持这样的错觉只有 StoreLoad 重新排序发生/对其他内核可见。

    自 P5 Pentium 以来,naturally-aligned loads/stores up to 64 bits are guaranteed atomic,但在此之前只有 32 位访问是原子的。所以是的,如果 386/486 有一个 MDR,它可能是 32 位的。但即使是那些早期的 CPU 也可能在 CPU 和 RAM 之间有缓存。

    我们知道Haswell and later have a 256-bit path between L1d cache and execution units,即 32 字节,而 Skylake-AVX512 有 64 字节的 ZMM 加载/存储路径。 AMD CPU 将宽向量操作分成 128 位块,因此它们的加载/存储缓冲区条目大概只有 16 个字节宽。

    Intel CPU 至少将相邻的存储合并到存储缓冲区内的同一缓存行,还有 10 个 LFB(行填充缓冲区)用于 L1d 和 L2(或离核到 L3 或 DRAM)之间的未决传输.


    指令解码:x86 是变长的

    x86 是变长指令集;在前缀之后,最长的指令超过 32 位。即使对于 8086 也是如此。例如,add word [bx+disp16], imm16 的长度为 6 个字节。但是 8088 只有一个 4 字节的预取队列来解码(与 8086 的 6 字节队列相比),因此它必须支持解码指令,而无需从内存中加载整个内容。 8088 / 8086 解码前缀一次 1 个周期,4 个字节的操作码 + modRM 绝对足以识别指令其余部分的长度,因此它可以对其进行解码,然后获取 disp16 和/或 imm16(如果它们不是)还没取。现代 x86 可以有更长的指令,尤其是 SSSE3 / SSE4 需要许多强制性前缀作为操作码的一部分。

    它也是一个 CISC ISA,所以在内部保留实际的指令字节并不是很有用;您不能像使用简单 MIPS 那样直接将指令位用作内部控制信号。

    在非流水线 CPU 中,是的,某处可能有一个物理 EIP 寄存器。对于现代 CPU,每条指令都有一个与之关联的 EIP,但许多指令同时在 CPU 内部运行。有序流水线 CPU 可能会将 EIP 与每个阶段相关联,但无序 CPU 必须在每个指令的基础上跟踪它。 (实际上是每个 uop,因为复杂的指令解码为超过 1 个内部 uop。)

    现代 x86 以 16 或 32 字节的块为单位进行获取和解码,每个时钟周期最多解码 5 或 6 条指令,并将解码结果放入队列中,以便前端发出到无序部分核心。

    另请参阅 https://stackoverflow.com/tags/x86/info 中的 CPU 内部链接,尤其是 David Kanter 的文章和 Agner Fog 的微架构指南。


    顺便说一句,您遗漏了 x86 的许多控制/调试寄存器。 CR0..4 对于 386 启用保护模式、分页和各种其他内容至关重要。您可以仅使用 GP 和段 reg 以及 EFLAGS 在实模式下使用 CPU,但如果您包含操作系统需要管理的非通用 reg,x86 具有更多的体系结构寄存器。

    【讨论】:

    • 首先,你是我的导师,我对你深表敬意;)。我想知道程序计数器/指令寄存器/位置计数器/内存缓冲寄存器/内存数据寄存器是同一个寄存器吗?并且它们在现代 CPU 中不存在?
    • @Ahtisham:当然,它们并不都是同一个寄存器。 PC 是一个指针,IR(如果存在)是它指向的指令值。 MBR/MDR(如果它们存在的话)都是不同的,并且也用于数据加载/存储(同样在一个没有拆分 L1 缓存的简单设计中,指令和数据访问不会并行发生)。现代 x86 CPU 需要知道每条运行中指令的地址(以防它出错),因此没有一个 single PC 寄存器,只有与 uop 关联的数据。 x86 从不使用“指令寄存器”,因为指令不是固定长度的,需要解码。
    • 作为一个 9 年的网络开发人员阅读这个答案感觉就像作为一个只听说过代码的 9 年级高中生第一次看到 JavaScript 的感觉概念。这听起来很先进,我正试图进入安全研究领域,学习汇编和 x86,但看看你的知识水平提醒我,我还需要 9 年才能回顾这个答案并理解它因为在学习了 9 年之后,我今天可以轻松阅读 JS 库的源代码。
    • @J.Todd:过去,您并不真正需要了解 CPU 在内部如何工作以确保安全性,只需了解指令如何执行的 ISA 纸上模型(除非您尝试利用具有竞争错误或内存顺序不足的多线程代码)。但是现在有了 Spectre,尤其是像 L1TF 这样的 MDS 漏洞,更不用说 Meltdown,突然 CPU 架构与安全性相关。 :/ 我对它的性能感兴趣,主要是因为它很有趣。
    • @PeterCordes 我相信你已经知道了(因为你当然会对 Movfuscator 感兴趣)但是以防万一你不感兴趣:3(4?)个演示文稿作者:DEFCON 的 Chris Domas 使用非常聪明的 x86 CPU 逆向工程找到embedded RISC micro-architecture backdoors in x86 CPUsfind proprietary x86 instructions (password protected MSRs),甚至是(using page fault analysis to fuzz) find malformed instructions that halt entire processors
    猜你喜欢
    • 2016-06-15
    • 2015-11-01
    • 1970-01-01
    • 2012-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多