【问题标题】:Why 2 LSB's of 32 bit ARM instruction address not used为什么不使用 32 位 ARM 指令地址的 2 个 LSB
【发布时间】:2014-06-12 12:21:37
【问题描述】:

我正在研究 ARM 指令架构,并且我读过指令是按字对齐存储的,因此指令地址的最低有效两位在 ARM 状态下始终为零。

Thumb 和 Thumb-2 指令的长度为 16 位或 32 位。指令以半字对齐的方式存储,因此在 Thumb 状态下指令地址的最低有效位始终为零。

在我对 AVR 等不同微控制器的一些研究中,在访问程序存储器时,我使用最低有效位来区分要访问的高字节或低字节。但那是关于数据内存访问的。

在 ARM 中,指令无论如何都是 32 位的,因此应该一次获取所有字节。

那么,最后两位用于获取指令的特定字节(Thumb 模式下为 1 位)并使用存储区。

PS:如果我要获取 4 字节长指令的单个字节,则需要 4 个周期,这是非常低效的,那么具有字节寻址能力的目的是什么,是因为新的 THUMB 类型指令是16 位宽但仍占用 32 位空间?

【问题讨论】:

  • 不清楚您要澄清什么;您的前两段是您问题的答案!
  • 为什么他们会在 ARM 或 THUMB 模式下使用银行来访问 32/16 位指令的单个字节。一条指令应该作为一个完整的单词来获取对吗?
  • 如果我要获取 4 字节长指令的单个字节,则需要 4 个周期,这是非常低效的,那么具有字节寻址能力的目的是什么,是因为新的 THUMB输入 16 位宽但仍占用 32 位空间的指令?
  • Thumb 指令占用 32 位空间 - 这就是使用它们的全部意义所在。一般而言,代码空间是字节可寻址的,而不是半字可寻址的,以与数据空间保持一致——一些嵌入式或配备缓存的 ARM 设计可以使用半哈佛架构构建以提高效率,但不需要特殊的数据指令访问代码存储器。请注意,通常都禁止未对齐的单词访问。
  • 具有字节可寻址性的目的是因为除了获取指令之外还有对内存的访问,而字节级可寻址性对于这些场景通常很有用。请注意,有些体系结构对于 8 位字节以外的事物是字可寻址的,但它们不像 8 位可寻址机器那样常见(一方面,如果我没记错的话,POSIX 需要 8 位可寻址性)。此外,还有一些 ARM 架构(例如 Cortex M3)具有有限的位级寻址能力。

标签: arm embedded memory-alignment instructions


【解决方案1】:

我认为您再次将指令访问与数据访问混合在一起。就数据访问而言,我们可以使用最后两位来获取 4 字节数据中的任何字节。

但是不使用最后两位的概念与访问 32 位指令的单个字节无关。正如您所说,一次访问一个字节以进行指令访问是非常低效的,也是不允许的。因此,为了强制执行此规则(在指令访问中不访问奇数边界处的字节),将不考虑最后两位。下图将对此进行解释:

地址是32位的:

|--0x00000007--|--0x00000006--|--0x00000005--|--0x00000004--|

|--0x00000003--|--0x00000002--|--0x00000001--|--0x00000000--|

专注于最后一点:

| 3-0011; 2-0010; 1-0001; 0-0000; |

| 7-0111; 6-0110; 5-0101; 4-0100; |

现在关注最后两个最低有效位。 我们的目标是不允许指令从位置 1、2、3、5、6、7 开始 因此,如果您检查两个 LSB,它们不会是 01、10、11 中的任何东西。 只允许“00”作为 2 个 LSB。现在因为它们是 00,所以当生成的地址是 4 的倍数时忽略它们一样好。

希望你能更好地形象化。

【讨论】:

    【解决方案2】:

    在 thumb 之前,所有的 arm 指令都是 32 位,4 个字节,并且让我们指定它们必须对齐,因此指令地址的低两位始终为零。然后拇指出现,16 位指令,因此地址的低位始终为零。他们添加了一个细微差别,当使用 bx 或 blx 切换模式时,lsbit 用于区分拇指和手臂。如果输入 bx 或 blx 时 lsbit 为零,则它保持或切换到 arm 模式,如果为 1,它保持或切换到 thumb 模式。请注意,当 lsbit 放置在被消耗的 pc 中时,它会从地址中剥离。在任一模式下运行时,pc lsbit 始终为零,而在 arm 模式下位 1 始终为零。

    arm 总线通常为 32 位或 64 位宽,它不像 x86 等那样是可变字指令集,现在使用的是 thumb2,但并不完全相同。因此,您不会提取单个字节,然后提取更多字节来隔离指令。 (并不是说现代可变长度指令集效率低下)。因此,手臂可以一次获取 8 条指令,这将是 64 位数据总线上的 4 个时钟周期(一旦握手结束)。那当然是缓存了,缓存与缓存相同或更多。每个内核/架构的取指都不同,内存控制器必须处理从任何通道上的一个字节到总线宽度的所有有效周期类型。

    我不知道你说的银行是什么意思?作为程序员,我们认为基于字节的地址是我们最小的可寻址项。当您使用实际的 rams 硬件时,人们开始剥离他们不使用的地址位,因此他们的 lsbit 可能与我们的不同。当您写入单个字节时,某些处理器总线不会将整个字节地址放在总线上,它们可能只会将字或双字地址放在总线上(2 或 3 个 lsbits 的零),然后使用字节掩码来判断哪些字节通道包含新数据以及您必须在目标上保留哪些字节通道。

    arm 网站 infocenter.arm.com 上的 amba/axi 总线文档中描述了 amba/axi 总线周期,它详细描述了每个事务的工作原理。一点都不复杂……

    【讨论】:

    • 从你的标题来看,如果你试图弄乱那些你会打赌预取中止或其他问题的位,那么这些低位肯定不会被忽略。
    【解决方案3】:

    请注意,问题标题仅适用于几个特定架构版本(ARMv3 和 ARMv4,在 32 位模式下) - 从 ARMv4T 开始,分支地址的 LSB 用于 ARM/Thumb 互通,正如 @dwelch 所拥有的那样著名的。在 v6M 和 v7M 上,切换指令集的尝试不会被忽略,并导致错误。

    在 v3 之前地址空间只有 26 位并且没有专用的 CPSR 时,r15 的低两位用于存储处理器模式(标志在高 6 位) - 一个标志设置写入到 r15 将更新 PC 和 PSR 位。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-18
      • 2022-07-22
      相关资源
      最近更新 更多