我是否需要拆分一个非常大的数字才能将其移动到ARM64中的32位寄存器中

问题描述 投票:0回答:1

我正在尝试在 ARMv8 AArch64(ARM64,如果你愿意的话)中编写一个程序,并且我想将一个非常大的数字移动到 32 位寄存器中。据我所知,正确的格式是

mov w20, 36383899

但是,我在某处看到这是不正确的,因为“指令是 32 位,这意味着指令以及目标寄存器地址占用了一些位”。 基本上,他们所说的是,在指令和目标寄存器地址占用了位之后,可能没有足够的空间来容纳您试图移入的数字。

他们说正确的形式应该是

mov w19, 13880 //first part of 36383899
lsl w19, 16    //logical shift left with shift count 16
mov w20, 14489 //second part of 36383899
orr w19, w19, w20 //this should be 36383899

现在,我正在运行的程序计划从 -50,000,000 循环到 50,000,000,并且我相信,因为我正在使用的值在 -2,474,483,648 到 2,474,483,647 的范围内(这是 32 位寄存器的范围),我应该没问题。

但是,由于单步执行 100,000,000 个循环是不可行的,我想问一下我是否需要将其分解,或者我可以像往常一样移动值吗?

如果我需要拆分,有没有方法来拆分数字?

assembly arm arm64
1个回答
0
投票

确实,并非每个 32 位数字都可以在一条指令中移入寄存器。正如你所说,这基本上是不可能的,因为指令是 32 位的。

然而,数字起作用的确切标准是复杂。每个 16 位数字都可以工作(零扩展或符号扩展),但其他一些数字也可以。与其尝试自己解决,不如尝试组装

mov w20, 36383899
。如果有一种方法可以将其编码在一条指令中,您的汇编器就会弄清楚;否则你会得到一个错误并可以继续下一步。

如果无法通过一条指令完成,那么您将需要不止一条指令。然而,您的答案中提出的顺序效率低下。首选方法是使用

movk
指令,它将任意 16 位值加载到寄存器的指定半字中,而其他位保持不变。所以要加载
0xdeadbeef
,你可以这样做

mov  w20, 0xbeef
movk w20, 0xdead, lsl 16

在您的情况下,您可以让汇编器来完成它,而不是手动计算高位和低位:

mov  w20, (36383899 & 0xffff)
movk w20, (36383899 >> 16), lsl 16
© www.soinside.com 2019 - 2024. All rights reserved.