【问题标题】:ARM mode, load 32bits constant. General caseARM模式,加载32bits常量。一般情况
【发布时间】:2015-02-24 14:48:28
【问题描述】:

我正在寻找一种在 ARM 模式下加载 32 位常量的通用方法。 不幸的是,我既不能使用“ldr rX,=const”(由于外部问题)也不能使用 movw/movt(我的目标是 armv6k)

这是我的尝试:

mov rX, 0
orr rX, (const&0x000000FF)
orr rX, (const&0x0000FF00)
orr rX, (const&0x00FF0000)
orr rX, (const&0xFF000000)

我的代码正确吗?你能建议我一个更好的方法吗?谢谢。

【问题讨论】:

  • 根据侧面的 related 链接,SO tag ARM + constants 至少给出了ARM 12bit constants,其中我引用了该问题的至少 5 个不同重复项。一些谷歌搜索会给出ARM blog,它必须回答你所有的问题。
  • @artlessnoise 请记住,在我的情况下,不能使用“ldr rX, =const”。在这种情况下,您提供给我的链接并不能解决问题。
  • 你可以使用ldr rX,=const;你的外部问题是什么,是你的问题。使用 ARM 汇编程序执行此操作的方法是这样的。您可以手动对此进行编码,并且您已接受使用ldr rX, =const 的答案。与orr 方法相比,还有许多其他方法可以使用更短的数学恒等式(取决于常数)来做到这一点。
  • @artlessnoise 我正在修补 Android 运行时 (ART) 以生成 ARM 模式代码。 ART 还必须处理 32 位常量加载,但在这种情况下,我不知道如何处理 PC 相关表达式(将常量放在函数末尾也是一个问题),所以我必须使用 mov/orr。这就是为什么在问题中我要求使用 generic(常量在编译时未知)方式来加载 32 位函数!=“ldr rX,=const”。因此,您提供给我的所有链接都没有用。我将 dwelch 的答案标记为正确,因为它为我提供了解决问题的方法(而且它不是 ldr)。

标签: arm


【解决方案1】:

arm 和 gnu 汇编器都允许使用以下语法:

ldr rX,=0x12345678

这导致在 pc 相对寻址范围内(如果可能)分配数据字 0x12345678 和编码为 pc 相对加载的指令,基本上:

ldr r0,my_data
...
my_data: .word 0x12345678

您的另一种选择是比您概述的少一条指令:

mov rX,0x0000078
orr rX,rX,0x00005600
orr rX,rX,0x00340000
orr rX,rX,0x12000000

现在至少使用 gcc,不了解 arm,如果您使用 ldr rX,=number 功能并且可以使用单个移动对数字进行编码,它将对该单个 mov 进行编码...

【讨论】:

  • 重读,如果你不能使用 ldr rX,=const (无法想象为什么)那么你需要做四个指令的事情。
  • 它不起作用的主要原因是未能发出.ltorg 指令。 .ltorg 放置的 'my_data' 可能远离缓存线(这就是为什么 movw/movt 更好)并且如果您只有一些指令(sub/add/rsb 等也可能会得到常数)它可能比ldr rx,=constant 更好。通常这是错误的,因为 .ltorg 数据可能会被其他代码使用做同样的事情,所以把它放在缓存中并不是一件坏事。
  • 另一个重要的一点是指令是ldr r0, [pc, #offset_my_data],它使代码可重定位,如果数据适合一个简单的移动,它将被使用(ldr r0,=0xfe将是mov r0, #0xfe并且不会向文字池发出任何内容。
猜你喜欢
  • 2010-12-08
  • 1970-01-01
  • 2011-11-22
  • 1970-01-01
  • 1970-01-01
  • 2018-07-13
  • 2010-12-04
  • 1970-01-01
  • 2011-10-27
相关资源
最近更新 更多