7

我真的很困惑,这个问题听起来可能很愚蠢,但我真的不确定当我们说指令大小是 32 位或 16 位时这意味着什么。

如果操作数大小是 32 位,那么我们说它是 32 位指令,如果操作数大小是 16 位指令。

或者每条指令都有操作码,如果操作码地址是 32 位,那么我们说指令是 32 位的。

我也在经历 ARM 架构,我读到的所有拇指指令都是 16 位的,但 ARM 模式指令是 32 位的。

指令大小完全取决于使用的架构还是取决于 CPU 运行的模式?

编辑:

http://www.xgc-tek.com/manuals/m1750-ada/m1750/x524.html

给定的链接表明16位指令由8位操作码和两个通用寄存器的4+4位组成。

ARM thumb 指令集是怎么回事?

4

2 回答 2

6

指令集(机器代码)的设计者,无论是一群人还是个人,都选择指令的大小。一些指令集,很多,是可变长度的,字面意思是一些指令比其他指令占用更多的位。操作码这个词非常适合那些遗留指令集,因为第一个字节通常决定了这是哪条指令,并且从第一个字节开始你添加了更多的操作数字节。我想到的这些操作码,x86、6502、z80 等不一定有不同的字段。例如,切换到 mips 看看我的意思是什么,固定长度的指令(尽管 mips 也有一个 16 位模式,你可以像 arm 一样跳进跳出)。很容易看出一些位的初始解码在哪里决定了几类指令中的哪一个,然后从那里几个位决定了指令,也称为操作码位。但是这个术语对我们今天拥有的所有指令集具有误导性。根据您所谈论的对象和指令集,您将整个指令称为操作码是对与错。

所以有人通过任何方法、经验、实验等来选择指令集是什么,以及他们可以在这些位中塞进什么。对于 arm 的情况,他们从 32 位指令开始,固定长度。就像 mips 一样让即时痛苦,但同时其他事情更容易(获取,解码等)。第一个拇指指令似乎被直接转换为与其对应的 arm 指令(ARM ARM 中记录了 arm 等效项),并且可能作为 arm 指令输入管道。那是那时,这是现在。但是你定义一个指令集及其机器代码并不重要,你设计的逻辑可以解析该指令集并按照你的意愿执行它,随着时间的推移,如果你幸存下来,你可能会像大多数公司所做的那样重新设计处理器使用不同的逻辑。让 100 名程序员给他们一个通用的 ascii 文件解析任务,你会得到 2 到 100 种不同的解决方案,从语言到样式再到算法,所有这些都是或有可能完成这项工作。与处理器相同,您可以为指令集发明与设计周期一样多的不同功能处理器。

ARM 拥有不断发展的传统 32 位指令集。在这里和那里添加了一条新指令,但在 64 位之前没有太大变化。有原始的 thumb 指令集,它是严格的 16 位指令(是的,分支是两个单独的 16 位指令,请阅读文档)。然后他们添加了 thumb2,它使用以前未定义的 thumb 指令来扩展 thumb 指令集,以恢复 arm 指令集的一些特性。这些指令必须成对,32 位,才能正确解释。还有jazelle,我仍然无法找到证明那是一个实际指令集的证据,从我能弄清楚的一切来看,它是一个你购买的软件包,而不是一个实际的指令集。也许有未记录的手臂或拇指指令来支持 jazelle,但我看不出哪里有指令集。然后 arm 有许多浮点指令集,但它们实际上是协处理器指令,其中重命名了字段并添加了助记符。

各种arm处理器内核使用逻辑来解码这些东西,也许有一个底层的通用指令集,上面所有的东西都输入,类似微码但更像vliw,或者它只是蛮力逻辑,如果这种模式那么解码这些位等,如果该模式等。

原始拇指指令集是目前唯一通用的整个手臂家族的指令集。出于这个原因,除了其他人之外,我还需要一些时间来学习它。最困难的事情,一旦你养成了习惯就不难了,就是让你的工具链按照你想要的方式构建东西,这在 arm 模式下,在 thumb 或一切 thumb 或一切 arm 中。Thumb 加上 thumb2 扩展,或者只是没有扩展的拇指。不幸的是 armv6 添加了 30 条左右 thumb2 指令 armv7 又添加了 140 条左右。armv7m 首先进入市场,armv6m 之后,然后只发布了单个 neon 等,所有这些都在工具链中造成混乱,用户试图为有问题的核心生成有效代码,只生成它支持的指令而不是它不支持的指令.

ARM ARMs, ARM Architectural Reference Manuals 和 ARM TRMs, ARM Technical Reference Manuals 描述了指令集(不幸的是,ARM 中的一些内核文档,TRM 中的其他内核文档),从那里你可以很容易地看到编码以及它们的内容和位置把东西塞进 ARM 指令和拇指指令中。我将从最古老的架构参考手册开始,也许他们称之为 ARMv5 ARM?我不记得了,但它是原始的 ARM ARM,包含 ARMv4T 内容,包括 arm 指令集和原始 thumb 指令集。然后你需要更多的手册来了解它们是如何演变的。

编辑,您的链接(链接在堆栈溢出方面不好,它们经不起时间的考验)

MIL-STD-1750A 是另一个处理器系列/指令集,机器代码根据该设计进行分解,并根据该设计进行解码。带有 thumb2 扩展的 thumb 基本上是一个可变长度指令集,因为您必须检查前 16 位以确定是否需要额外的 16 位才能完全理解指令,这在 x86 系列等可变长度指令集中很常见。

就 arm 和 mips 而言,您处于一种或另一种模式是一种模式。就其他设计为可变长度的指令集而言,它不一定是模式问题,而只是解码器一直如何工作。从 16 位到 32 位再到 64 位时,x86 确实必须玩游戏。我还没有学习新的 arm 架构,很可能它可以支持没有 64 位指令集的 64 位寄存器(例如,x86 仍然是一个 8 位指令集,最多支持 64 位寄存器)但我不知道那是不是他们做了什么。

编辑 2

感谢@dwelch 的详细回答,你总是在那里帮助人们。我的疑问很简单。假设我们有 16 位指令添加 r1,r2 并且操作码的大小是 8 位,这是否意味着 r1 和 r2 可以它的值不超过 15(r1 和 r2 只有 8 位可以在它们之间共享)。是真的吗?- </p>

我认为 auselen 试图以这种方式回答这个问题。

add r1,r2 的机器代码只是告诉处理器一些事情,这是一个 add 操作,操作数是寄存器 r1 和 r2 的内容,结果进入 r1。无论 r1、r2 和其他寄存器是什么,总是 32 位。指令大小与此无关。r1 的所有 32 位都与 r2 的所有 32 位相加,整个 32 位结果放在 r1 中。

困难在于直接的价值观。如果您想将立即数 1 添加到 r1,那么还有空间。但是,如果您想将值 0x100000 添加到 r1,那么您不能在一条指令中使用拇指模式执行此操作,您可以使用 arm 指令,我认为使用 thumb2 扩展但不能使用拇指,因为指令集的设计没有考虑到这一点,无论指令集有多大,您都无法在一条指令中完成您想做的所有事情。拇指要将该常量添加到寄存器中,您需要使用另一个寄存器,然后从内存中加载该常量(通过要求汇编程序在构建二进制文件时将该值放入内存中),或者您可以例如将 mov 1 放入寄存器,然后将其左移 20 位。

Mips 和 arm 使用不同的方式让它们的即时指令在固定长度的指令内工作,mips 基本上给你一个高 16 位或低 16 位,并且有一组指令,其中一半指令是即时指令。Arm 通常将其分解为 8 位和一个移位操作数,以便您可以创建任何立即数,只要唯一位在 8 位集群中(加上一些其他规则)。要使用纯指令,mips 需要两条指令将任何可能的 32 位值加载到寄存器中,arm 模式下最多需要 4 条指令。拇指模式需要的远不止这些。

回到主题,看看 x86 指令集,单个 8 位操作码可以告诉处理器对两个 64 位寄存器执行一些操作。这不仅仅是一个 8 位操作码,而是整个指令只有 8 位。有时16,有时更多。但关键是指令指定哪个寄存器只需要几位。寄存器的大小是指令集设计的一部分,但不必并且通常与指令的大小无关。对于任何操作,r1 和 r2 可以具有介于 0x00000000 和 0xFFFFFFFF 之间的任何值。

于 2013-10-29T14:25:07.680 回答
4

ARM(不包括新发布的 64 位)有两个由固定大小的指令组成的指令集。经典的称为 ARM,每条指令都是 32 位的。后一种称为 Thumb(实际上是 Thumb2),它可以有 32 位或 16 位指令。有些 ARM 内核只支持 ARM、ARM+Thumb 和只支持 Thumb 指令集。如果一个内核同时支持这两种模式,它具有更改活动指令集选择的指令,并且指令流可以在不同集之间跳转(互通)。

ARM 指令可以包含固定的操作数,但它们永远不会像指令大小一样大。一些指令还支持对操作数的操作,如移位、旋转,这给您的印象是可以使用一条指令加载 32 位值。

示例 #1

a = 0x1;

拇指

2001        movs    r0, #1

手臂

e3a00001    mov r0, #1

示例 #2

a = 0xC0000000;

拇指

f04f 4040   mov.w   r0, #0xC0000000

手臂

e3a00103    mov r0, #0xC0000000

示例#3

a = 0x12345678

拇指

f245 6078   movw    r0, #0x5678
f2c1 2034   movt    r0, #0x1234

手臂

e3050678    movw    r0, #0x5678
e3410234    movt    r0, #0x1234
于 2013-10-29T11:57:55.433 回答