实际上,如果您搜索您要询问的内容: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 或指令集,它只是特定处理器能够理解的指令集。某处有定义机器代码和指令操作的文档,通常与该文档一起的是一种汇编语言表示,基本上至少有一个汇编程序可以理解。