assembly 用于加载1字节非零扩展的Aarch64指令

mdfafbf1  于 2023-06-23  发布在  其他
关注(0)|答案(1)|浏览(126)

在aarch64上有没有一种方法可以将单个字节从内存加载到寄存器中,而不需要零扩展?我知道LDRB例如零扩展。

von4xj4u

von4xj4u1#

不是直接的。ARM指令集的一般原则是,对于大多数指令,目的地寄存器被完全重写。这样做的一个好处是指令不会引起对目的地寄存器的读取依赖性,从而使其更有效地乱序执行。
因此,当您从内存中读取单个字节时,目标寄存器的剩余56位必须用 something 覆盖。您的选项包括:

ldrb w0, [x1]  // bits 8:63 of x0 are cleared
ldrsb w0, [x1] // bits 8:31 set equal to bit 7, bits 32:63 are cleared
ldrsb x0, [x1] // bits 8:63 set equal to bit 7

如果你想对高位做些其他的事情,你需要一个或多个额外的指令。例如,如果希望加载的字节位于特定寄存器的低8位,同时保持位8:63不变,可以这样做

ldrb w2, [x1]
bfi x0, x2, #0, #8

如果需要,可以将其插入到#0以外的其他位置。但是对于加载指令本身,您确实需要一个临时寄存器(这里是x2)。(注意bfi和它的亲属是上述原则的例外,因为它们确实“合并”到目标寄存器中。
在SIMD方面,可以使用ld1加载到SIMD寄存器的特定通道中,保持其余通道不变。所以你可以

ld1 v0.b[11], [x1]

将字节加载到SIMD寄存器0的元素11中。

相关问题