【问题标题】:What is the definition of instruction set architecture?指令集架构的定义是什么?
【发布时间】:2020-01-04 01:00:22
【问题描述】:

我正试图弄清楚指令集架构 (ISA) 究竟是什么。根据我的阅读,我有两种解释。

我的第一个解释是,ISA 是所有寄存器、汇编指令和伪指令、汇编指令和指令格式的集合,这些集合构成了可用于对实现指令集的处理器进行编程的汇编语言。

我的第二种解释是,ISA 是计算机单词和汇编指令之间的双射映射。例如,指令add $s0, $t0, $t1 计算值$t0 + $t1 并将其存储在$s0 中,对应于字000000 bin($t0) bin($t1) bin($rd) 00000 10000,其中bin($reg) 是寄存器$reg 的二进制表示(使用MISP在这个例子中)。

我不认为这些解释是相互排斥的,因为它们可以共存,前提是为给定 ISA 用汇编语言编写的程序将为所有实现 ISA 的处理器汇编成相同的机器代码;但是,我也不认为这很明显,因为如果 ISA 仅指汇编语言的结构(正如我的第一个解释所暗示的那样),那么同一个程序可以根据处理器组装成两种不同的机器代码表示。

有人能澄清一下指令集架构这个术语究竟包含什么吗?

【问题讨论】:

  • 您的两个定义都定义了“汇编语言”。指令集架构是由 CPU 实现的指令集、指令编码和行为。不管你用什么符号(汇编语言)以人类可读的形式写下这些指令,它仍然是同一个 ISA。
  • @fuz “指令编码”是什么意思?
  • 指令编码是将支持的指令编码为二进制的方式。像 ARM 等一些 ISA 对同一指令集有多种编码。
  • 那么在MIPS中,指令编码是R-type、I-type和J-type指令格式吗?
  • 所有这些格式都是 MIPS 指令编码的一部分。 MIPS 只有一种指令编码。例如,ARM 有 ARM32、Thumb、ARM64 以及可能的其他一些方案。

标签: assembly cpu-architecture instruction-set


【解决方案1】:

指令集架构名义上定义了机器可以执行的每条指令,以及效果、条件和可能的异常等内容。

指令是根据它们操作的数据来定义的,这些数据称为操作数。通常,指令将聚集成组,允许可能的操作矩阵,即opcodes,和操作数(包括addressing modes)。 MIPS I-Type、J-Type 是这些集群的示例,称为格式。

指令是 ISA 的关键。例如,如果没有指令可以引用该寄存器(例如作为操作数),则提供寄存器是没有意义的。这可能就是我们称之为指令集架构的原因,因为我们通过指令定义的镜头来实现寄存器和行为。

指令集架构定义了处理器的machine code,以及处理器在特定状态和指令下的行为。

机器码中的指令是二进制数字的字符串,CPU 将其解释为执行。

在机器代码中,没有汇编指令、标签、变量名等……;这些都是汇编语言的产物。在机器代码中,表示指令(包含操作码和操作数)的二进制数字串和 CPU 操作的数据都被 CPU 简单地视为数字(位串),如果您愿意的话。

汇编语言几乎可以将 1:1 转换为机器代码指令,尽管指令、宏、伪指令、数据和其他东西使这更像是一种近似而不是事实。

通常,芯片制造商会在指令集架构的同时定义一种汇编语言——然而,汇编语言并不是拥有 ISA 的必要条件。 ISA 真正意味着理解哪些数字(位串)对处理器有什么意义。

事实上,芯片制造商和/或其他人(例如 Microsoft、Linux)通常也会定义一个 Application Binary Interface,其中包括一个 calling convention,以帮助软件消费者编写可互操作的软件。

计算机单词和汇编指令之间的双射映射

是和否:是的,如果您所说的汇编指令是指每个可能指令的操作和行为的定义。

我会说机器代码位串之间的映射和处理器如何解析编码的详细定义,以及它们的作用,即它们对计算机状态的影响。

【讨论】:

    【解决方案2】:

    实际上,如果您搜索您要询问的内容:6502 指令集、mips、指令集等,您会发现某种形式的文档,其中包含指令列表和有关每个指令的信息。有一个底层架构,所以它是一个指令集架构。

    来自谷歌搜索的 8051 指令:

    ADD A,R0    0x28    1   C, AC, OV
    

    我省略了列标题,但是从人类可读的部分来看,这条指令添加了寄存器 R0 和累加器,并将其保存在累加器中。我在谷歌搜索时看到的命中实际上每条指令都有很多很好的信息。 C、AC、OV 在标志列中表示进位标志受到影响(从第 7 位进位),辅助进位受到影响,对于此 ISA 意味着第 3 位的进位进入标志和 OV,溢出标志,为有符号溢出(自行执行视为无符号溢出)。

    0x28 是指令的编码。处理器看到的是 00101000 位,这些位告诉处理器执行一系列操作,读取 A 寄存器,读取 R0 寄存器,添加它们,将结果存储在 A 寄存器中,将标志存储在处理器状态和继续下一条指令。

    作为一名程序员,您通常认为/看到 ADD A,R0,但处理器无法对其进行操作,它对位进行操作。

    这是一组指令,因为有一个列表,一个特定于该处理器的“集合”。

    INC R1  0x09    1   None
    

    增加R1寄存器,编码为0x09,不影响标志(单字节指令)。

    现在,许多早期处理器(CISC)就是这样开始的,它们通常在某些方面进行了微编码。 0x09 可能指向具有微指令列表的 rom,将 r1 读取到 alu 操作数输入之一,将 0x01 强制到另一个 alu 操作数输入,执行加法,将 alu 输出写入 r1 寄存器。完成。

    它的意义与今天的 RISC 意义相同。处理器实际上是手工设计的。就像起草人会使用丁字尺、三角形、铅笔和纸来设计房子一样,芯片的每一层都被设计成大尺寸,以便以后缩小以创建芯片的每一层。有了这么多的手工/人工工作,您不想创建数千个复杂的指令步骤,而是制作了一小部分东西,例如可以提供 alu 输入 0 的多路复用器,提供 alu 输入 1 的多路复用器,等等,然后你有微指令驱动多路复用器来控制这些alu输入并控制寄存器上的锁存器,以便寄存器可以将alu输出“写入”到它。控制内存接口,等等。几乎是一个 risc 指令集,但级别更低。然后,您可以在其中构建带有(可能)一次性可编程ROM的芯片。并且 0x09 可能变成了 0x090 到该 rom 的地址,每条指令最多允许 16 条微指令。

    去看看visual6502页面

    后来,当我们开始能够使用计算机制造计算机并可以开始进行更复杂的设计并相信它们可以在没有太多旋转的情况下工作时,编程和处理器的概念也得到了发展。你今天快进,你有一个 mips 或 arm 或 risc-v 或许多其他 32 位指令,其中不需要专用的“操作码”,这取决于架构你有最初解码的特定位以确定什么这是指令的类别(alu 操作,内存操作等),有时这些初始位说明整个故事,其余位定义使用的寄存器。所以现在你会看到这样的东西:

       0:   3001        adds    r0, #1
       2:   3101        adds    r1, #1
       4:   3201        adds    r2, #1
       6:   3301        adds    r3, #1
       8:   3401        adds    r4, #1
       a:   3501        adds    r5, #1
       c:   3601        adds    r6, #1
       e:   3701        adds    r7, #1
      10:   1800        adds    r0, r0, r0
      12:   1840        adds    r0, r0, r1
      14:   1880        adds    r0, r0, r2
      16:   18c0        adds    r0, r0, r3
      18:   1900        adds    r0, r0, r4
      1a:   1940        adds    r0, r0, r5
      1c:   1980        adds    r0, r0, r6
      1e:   19c0        adds    r0, r0, r7
    

    s 并不意味着有符号,它意味着我想要更改标志,这个指令集 (ARM THUMB),或者至少它的父指令集 ARM 可以选择不在指令上设置标志,你可以选择与否。第二列是“编码”。处理器操作的位,您可以看到,当我更改其中一个寄存器时,有些位会发生变化,而其他位则不会。

    16 位中的一些告诉处理器这是一个带有立即指令的加法寄存器,其他位指示寄存器和立即指令。或者下半部分表示这是一个带寄存器的加法寄存器,其他位表示每个操作数对应哪些寄存器。

       0:   e2900001    adds    r0, r0, #1
       4:   e2911001    adds    r1, r1, #1
       8:   e2922001    adds    r2, r2, #1
       c:   e2933001    adds    r3, r3, #1
      10:   e2944001    adds    r4, r4, #1
      14:   e2955001    adds    r5, r5, #1
      18:   e2966001    adds    r6, r6, #1
      1c:   e2977001    adds    r7, r7, #1
      20:   e0900000    adds    r0, r0, r0
      24:   e0900001    adds    r0, r0, r1
      28:   e0900002    adds    r0, r0, r2
      2c:   e0900003    adds    r0, r0, r3
      30:   e0900004    adds    r0, r0, r4
      34:   e0900005    adds    r0, r0, r5
      38:   e0900006    adds    r0, r0, r6
      3c:   e0900007    adds    r0, r0, r7
    

    现在arm、mips、risc-v等指令集或许有32位指令和16位指令。显然 16 位指令没有足够的位来做那么多,但是如果使用 32 位和 16 位指令如上面的 ARM 所示可以告诉处理器添加 r0=r0+r1,那么您可以明智地使用您可以节省空间可以节省一些空间。每个架构都有如何切换模式的规则,所以不要假设你可以在每条指令上触发。 Risc-v 你可以逐条指令,mips 和 arm 你必须专门从一种模式切换到另一种模式并保持在一个模式直到你切换回来。

    (上面第一列是地址,第二列是该指令的指令编码,然后是反汇编(汇编语言))

    这是一些 risc-v

      b0:   00140413            addi    x8,x8,1
    

    他们不使用 r0,r1,r2,r3,他们使用 x0,x1,x2,x3... 助记符的选择和使用 r0 vs x0 vs w0 等等,如果你考虑一下,一个或有些人只是简单地决定这就是我们想要设计汇编语言的方式,这些是我们给出指令的名称和寄存器等等。机器码才是最重要的,我可以很容易地为 risc-v 编写一个汇编程序,其中包含我自己编写的汇编语言的指令,结果是:

      b0:   00140413            add r8,r8,#1
    

    因为汇编语言是由汇编程序定义的,即解析它的程序,很少有像一些新的高级语言那样的汇编语言标准文档。只要机器代码正确,您就可以编造任何语言来生成这些指令。

    不仅仅是 Intel ATT 与 Intel 的事情,而且 arm 组装器在一定程度上在 arm 随时间推移生产的各种设备之间相互不兼容,kiel 现在 arm、gnu 和其他。虽然人们喜欢生活在这样的错觉中,即汇编语言意味着最好是一对一地表示机器代码指令的助记符。指令确实如此,但是该汇编程序的语言有很多非指令或伪指令部分,也就是说,您大多看到了变化,但即使在 arm 汇编程序和 gnu 之间,甚至是注释字符和其他简单的东西像那样变化。

    指令集架构通常缩写为 ISA 或指令集,它只是特定处理器能够理解的指令集。某处有定义机器代码和指令操作的文档,通常与该文档一起的是一种汇编语言表示,基本上至少有一个汇编程序可以理解。

    【讨论】:

      猜你喜欢
      • 2020-01-04
      • 2014-02-10
      • 2017-09-03
      • 2018-03-12
      • 2021-07-06
      • 2015-12-24
      • 2012-05-25
      • 2020-02-11
      • 2020-05-19
      相关资源
      最近更新 更多