如果目标地址不是4字节对齐的话,THUMB2引用指定LDR PC, [PC, #imm]
(类型2)是不可预测的。
根据我的经验,在某些处理器上,这种方法非常好,而在其他处理器上则很糟糕(这就是为什么我需要花费很长时间才能将故障跟踪到这个对齐问题)。
所以我想知道是否有一些真正的解释(除了“只是不要这样做”)。
答案 0 :(得分:2)
使用像这样的ARM语言通常意味着在过去或现在的某个时刻,他们有一个特定的核心,它不起作用。所以就是不要这样做。可以与您的核心完美配合。它可能与指令集有任何关系,也可能没有任何关系,它们总是可以使指令工作,如果他们想要,对齐或不对齐,只需要关闭门。这就是为什么一个或多个特定实现很可能出现问题并且在找到之前已经发布的原因。
在ARM过去,可能仍然如此,当他们专门实现了事实上可预测的东西时,他们会使用这种语言,并且他们使用它作为一种方式来查看您是否使用了被盗代码或随你。如果你克隆了一种ARM类的东西,那就说明了。我认为picoTurbo几乎涵盖了这一点并把它放到了床上。 ARM的法律团队现在做了很短的工作。
程序计数器尤其有点凌乱,尤其是管道,两个前面的东西都是合成的,现在可能已经是橡树天了。一般来说,使用逗号右侧的电脑只是一个坏主意,除了特定情况(电脑相对负载,跳转表等),所以你可能会看到与PC相关的那种语言,所以他们没有添加代码和时钟周期,使该指令只适用于右侧的pc。在这种情况下(pc相对负载),它们可能还有一个或多个实现相互切割和粘贴的问题,或者出于性能或门数或时序收敛的原因,他们制定了这个规则。时序收敛,您的设计只能像帐篷中最长的杆一样快,最长,时间,组合信号用于解决制造和温度以及其他环境因素加边际的变化。因此,在计算这些内容之前,检查它们并确定,我们是否要将其拆分为两个或更多时钟,是否与特定功能相关联,我们是否只想删除该功能。重复合成和时序收敛,直到您预期的最大时钟频率达到或高于您对此产品的预期。
在这种情况下,它们也可能没有捕获未对齐的访问,而不是4字节对齐是未对齐的访问,并且它们可能没有正确实现它,假设它将被困住或谁知道原因。你也许可以尝试测试一下。通过在未对齐地址的任一侧获取或种植特定字节,然后在可能落地的位置组合代码。除非你是一个芯片供应商,否则你无法看到这一点(如果它没有陷阱),作为一个芯片供应商,你将能够模拟这一点,看看究竟发生了什么,当然你也会得到代码,看看到底为什么如果你有一个不起作用,它就无法工作。
在早期的ARM ARM(ARMv4T / ARMv5T和一些ARMV6)中,它在LDR上更为通用,[,]
如果存储器地址不是字对齐且没有数据中止,则写入目标寄存器的值是不可预测的。
甚至不会将PC用作一个或多个寄存器。
TL; DR。很可能它是两件事之一,1)他们至少有一个核心有一个bug,固定在同一家族的后期核心或其他设计中。 2)他们有一个设计原因(通常是时间/性能),这使得不希望实现未对齐的访问并允许它产生垃圾,可能不是不可预测的,但不值得对结果的冗长解释,因为它无论如何都不会帮助你
仅仅因为它在一个核心上工作一次对你来说并不意味着它总是有效,你可能会对代码和核心的问题感到幸运。如果您可以访问勘误表,您可以找到答案的原因和解决方法。从ARMv4T到现在的所有arm内核都支持Thumb,并且许多内核都是从头开始做的,所以只是因为你在一个勘误中发现它有一个修复并不意味着其他设计依赖于文档说不要这样做而且没有懒得让它发挥作用。
答案 1 :(得分:1)
主要原因(我认为)是加载PC或SP的指令有副作用,并且难以在CPU中有效管理。由于ARM指令集,较新的指令集(包括Aarch64)会限制具有这些副作用的指令。