ARM模式,加载32位常量。一般情况

ARM模式,加载32位常量。一般情况,arm,Arm,我正在寻找一种在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) 我的代码正确吗?你能给我一个更好的建议吗

我正在寻找一种在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)

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

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,=数字功能,并且数字可以通过单个移动进行编码,它将对单个mov进行编码…

如果您不能使用ldr rX,则重新读取,=const无法想象为什么需要执行四条指令。它不起作用的主要原因是未能发出.ltorg指令。由.ltorg放置的“my_data”可能远离缓存线这就是为什么movw/movt更好的原因,如果您只有几个指令sub/add/rsb等也可以获得常量,它可能比ldr rx=常量更好。一般来说,这是错误的,因为.ltorg数据可能会被其他做同样事情的代码使用,所以将其放入缓存不是一件坏事。另一个重要的一点是指令是ldr r0,[pc,offset_my_data],它使代码可重定位,如果数据适合简单移动,则将使用ldr r0,=0xfe将是mov r0,0xfe,不会向文字池发出任何信息。根据侧面的相关链接,至少给出了,其中我引用了这个问题的至少5个不同副本。一些谷歌搜索会给出必须回答您所有问题的答案。@artlessnoise请记住,在我的例子中,ldr rX,=const不能使用。在这种情况下,您提供给我的链接无法解决问题。您可以使用ldr rX,=const;无论你的外在问题是什么,都是你的问题。使用ARM汇编程序执行此操作的方法如下。您可以手动对此进行编码,并且您已经接受了一个回答,即使用ldr rX,=const。与orr方法相比,还有许多其他方法可以使用更短的数学恒等式(取决于常数)。@artlessnoise我正在修补Android运行时ART以生成ARM模式代码。ART还必须处理32位常量加载,但在这种情况下,我不知道如何处理PC相对表达式,将常量放在函数末尾也是一个问题,因此我必须使用mov/orr。这就是为什么在我问的问题中,编译时不知道加载32位函数的方法!=ldr rX,=常数。因此,您提供给我的所有链接都没有用处。我认为dwelch的答案是正确的,因为它为我提供了解决问题的方法,而不是ldr。