指令集架构的定义是什么?

What is the definition of instruction set architecture?

我正在努力思考指令集架构 (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 仅指汇编语言的结构(正如我的第一个解释所暗示的那样),那么同一个程序可能会根据处理器的不同被汇编成两种不同的机器代码表示形式。

有人可以澄清术语 指令集体系结构 到底包含什么吗?

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

指令是根据它们所操作的数据来定义的,这些数据被称为操作数。通常,指令会聚集成组,允许可能的操作矩阵,也就是 opcodes, and operands (to include addressing modes)。 MIPS I-Type、J-Type 是这些块的示例,称为格式。

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

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

机器代码中的指令是二进制数字串,CPU 解释也就是执行。

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

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

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

事实上,芯片制造商 and/or 其他人(例如 Microsoft,Linux)也会定义 Application Binary Interface, which includes a calling convention 来帮助软件消费者编写可互操作的软件。

bijective mapping between computer words and assembly instructions

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

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

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

来自 google 的 8051 指令:

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

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

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

作为程序员,您通常 think/see ADD A,R0 但处理器无法对其进行操作,因为它对位进行操作。

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

INC R1  0x09    1   None

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

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

它的意义与今天 RISC 的意义相同。处理器实际上是手工设计的。就像 drafts-person 会使用 t-square 和三角形、铅笔和纸来设计房子一样,芯片的每一层都设计成大尺寸,以便稍后缩小以创建每一层芯片。有了这么多 hand/human 工作,您不想创建数千个复杂的指令步骤,而是制作一小组东西,例如可以馈送 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),或者至少它的 parent 指令集 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 位指令没有足够的位来做那么多,但明智地使用你可以节省 space,如果上面 ARM 所示的 32 位和 16 位指令都可以告诉处理器添加 r0=r0+ r1,那么你可以节省一些space。每种体系结构都有关于如何切换模式的规则,因此不要假设您可以在每条指令上触发。 Risc-v 你可以一个指令接一个指令asis、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 和其他汇编器。虽然人们喜欢幻想汇编语言意味着助记符,它们完美地一对一地表示机器代码指令。对于指令来说确实如此,但是该汇编程序的语言有很多 non-instruction 或伪指令部分,那是您最常看到的变化,但即使在 arms 汇编程序和 gnu 之间,甚至注释字符和其他像这样简单的事情会有所不同。

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