【问题标题】:Why can't the first two arguments to the MUL expression on ARM7 be the same?为什么 ARM7 上 MUL 表达式的前两个参数不能相同?
【发布时间】:2015-10-09 20:44:57
【问题描述】:

我一直在帮助进行 ARM7 汇编语言课程的实验,今天遇到了一个学生输入以下表达式的问题:

MUL R0, R0, R1

代码没有编译。解决方法是将表达式改为:

MUL R0, R1, R0

即MUL 的前两个参数不能是同一个寄存器。我已经知道这一点,因为它是 ARM 文档的一部分: http://infocenter.arm.com/help/topic/com.arm.doc.dui0489i/DUI0489I_arm_assembler_reference.pdf

学生很高兴他们的问题得到解决,但我很沮丧,因为我不知道为什么 ARM7 要求像这样传递参数。我认为这可能与乘法器移位和加法时用于存储中间值的寄存器之一有关,但我什至不确定乘法是否在 ARM 上工作(事实上,我相当当然不是)。为什么参数的顺序在这里如此重要?

【问题讨论】:

  • 最有可能是 ip 中的错误。尤其是在较早的 arm7 天,您的代工厂布局不是 verilog。也有错误,他们可以尝试违反规则,看看你是使用真正的手臂 ip 还是克隆或窃取了手臂 ip……手臂中的一些“不可预测的结果”项目属于这一类(国际海事组织)。在某些情况下,实际错误仅在某些内核上而不在其他内核上。如果您可以使用旧纸质版本的手臂进入电子设备,您可以看到这些东西来来去去。

标签: assembly arm multiplication arm7


【解决方案1】:

Rn 必须不同于 ARMv6 之前架构中的 Rd”这一事实表明,这是在原始三阶段 ARM 流水线中如何实现乘法的设计限制.在 ARMv6 之前是指具有 ARM7 或更早设计的 CPU,这些都使用简单的三级流水线。不像大多数指令乘法需要多个周期来执行,并且根据指令集的限制,您的怀疑似乎是正确的,目标寄存器 Rd 在每个周期都被修改以计算结果。

论文Verifying ARM6 Multiplication by Anthony Fox 支持这一点,图 4 显示了在 ARM6 内核执行乘法指令期间如何修改 Rd(以下重新格式化以适应 Stack Exchange 标记的限制):

  • t3

    • 获取指令
    • 增加程序计数器
    • mul1 设置为reg[Rs]
    • borrow设置为false
    • count1 设置为零


    • 如果累加,则将reg[Rd] 设置为reg[Rn],否则为零

    • mul 设置为mul1[1:0]
    • mul2 设置为mul1[31:2]
    • borrow2 设置为borrow
    • mshift 设置为MSHIFT2(borrow,mul,count1)
  • tn

    • alub 设置为reg[Rm] 左移mshift
    • alua 设置为reg[Rd]
    • mul1 设置为mul2[29:0]
    • borrow 设置为mul[1]
    • count1 设置为mshift[4:1] + 1


    • reg[Rd]设置为ALU6<sup>*</sup>(borrow2,mul,alua,alub)

    • mul 设置为mul1[1:0]
    • mul2 设置为mul1[31:2]
    • borrow2 设置为borrow
    • mshift 设置为MSHIFT2(borrow,mul,count1)
    • 更新CPSRNZC 标志(如果设置了S 标志)
    • 如果是最后一次迭代,则解码下一条指令

图。 4:乘法指令的ARM6实现。每个周期被拆分 分为两个阶段。 tn 循环重复直到 MULX(mul2,borrow,mshift) 是真的。 当Rd 等于Rm 或十五时,寄存器Rd 不会更新。

因为reg[Rd]在初始设置周期t3和重复tn期间都被修改了em> 如果Rd == Rm 循环结果将是垃圾,因为步骤“将alua 设置为reg[Rm] 左移mshift”期望读取Rm 的原始未修改值,而不是当前中间值存储在Rd中。

某些 ARM7 CPU 有一个“快速乘法器”,每个周期处理 8 位,而不是如上所述的每个周期 2 位,但它似乎也在计算过程中修改了寄存器。

【讨论】:

    【解决方案2】:

    我猜这是一个或多个内核的 ip 中的错误。

    尤其是在 arm7 的日子里,你得到了一个从 arm 而不是源代码到核心的布局,让编译器解决一个 ip 错误,而不是修复错误,召回所有单元,报废如果在供应商投资购买口罩或已投入生产后发现错误,则正在处理中。

    使用 time arm(和其他人)可以阅读更多内容并确定您拥有的特定内核,并遵循勘误表(尽管 Linux 之类的软件在这方面做得很糟糕,将错误的勘误表应用于错误的内核)以了解哪些错误避免。

    一些“不可预测的结果”实际上是可以预测的,只是被破坏了,并且可以被 arm 用来确定这是一个克隆还是被盗的 ip。

    【讨论】:

    • 哇,这真的很有趣。非常感谢。因此,这可能是硬件中的一个错误,它比修复更便宜,或者它是一个故意的错误,作为检测克隆 ip 核心的尖峰而引入?凉爽的! :D
    • 这是我的猜测...这是一个错误,或者是对实施性质的限制...我认为这不是对 ip 的有意保护,但任何勘误表任何公司都是知识产权保护的一种形式,因为他们知道问题的真正性质及其影响,而不是仅仅告诉公众它破产了不要使用它。
    • 故意的 ip 保护例如在未定义的指令或寄存器中,我会假设...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 2021-04-01
    • 1970-01-01
    • 2019-02-19
    • 1970-01-01
    相关资源
    最近更新 更多