我正在阅读来自ARM的SVE whitepaper并遇到一些令我感到奇怪的事情(在非SVE示例中):
xzr
我不知道这个x8
注册是什么,所以我查了一下,发现some content from ARM说明在许多情况下,它是零的同义词。
所以看起来x8
被初始化为零,这是有道理的,因为它是在0
用作循环计数器的循环之前执行的。
我不明白的是,为什么不使用文字xzr
代替mov x8, 0
?例如:
xzr
总结一下,我的问题是:为什么可以在这里使用0
注册而不是文字org.springframework.security.authentication.AccountStatusUserDetailsChecker
?
答案 0 :(得分:4)
我认为mov x8, xzr
vs mov x8, #0
比较是一种红色的鲱鱼。
正如@ old_timer的答案显示的那样,没有编码收益,而且很可能(虽然我没有检查过)很少或没有管道性能提升。
xzr
给我们的是 - 除了@InninitelyManic的答案之外的虚拟寄存器 - 是访问零值操作数而无需加载和占用实际寄存器。这样可以获得少一个指令的双重好处,还有一个寄存器可用于保存“真实”指令。数据
我认为这是原始'some content from ARM' referred to in the OP忽略指出的一个重要特征。
我的意思是mov x8, xzr
vs mov x8, #0
是红鲱鱼。如果我们将x8
归零以便随后修改它,那么使用xzr
或#0
非常随意(尽管我倾向于{{1} }更明显)。但是,如果我们将#0
纯粹归零以便为后续指令提供零操作数,那么我们最好还是使用 - 在允许的地方 - x8
而不是{{1} }作为 指令中的操作数,而不是归零xzr
。
答案 1 :(得分:2)
mov x8,xzr
mov x8,#0
mov x8,0
产生
0000000000000000 <.text>:
0: aa1f03e8 mov x8, xzr
4: d2800008 mov x8, #0x0 // #0
8: d2800008 mov x8, #0x0 // #0
除了允许立即没有英镑符号之外,没有其他真正的惊喜。这不是一个指令大小问题(同样毫不奇怪,x86例如xor rax,rax比mov rax便宜,0),也许有一个管道性能增益(尽管流行的信念指令需要多个时钟开始完成)
最有可能是个人偏好我们有这个很酷的mips,就像总是零注册的东西,让我们只是为了好玩。
答案 2 :(得分:0)
这两条指令应该是相同的 - 无论是效果还是预期的表现。
它们实际上是更多通用指令的别名。
mov x8, 0
编码为orr x8, xzr, 0
mov x8, xzr
编码为orr x8, xzr, xzr
别名很有用,因为它们使ASM更具可读性。
第二种编码说明了为什么使用零寄存器xzr
会很有用。因为我们知道xzr总是为零,所以我们可以重用orr
的{{1}}指令。没有它,mov
将需要不同的编码,因此会浪费编码空间。
答案 3 :(得分:0)
这个答案不是四十四岁四十四岁。对OP。
XZR可用于丢弃结果;例如,&#34; ldr xzr,[sp],16&#34;。见下面的GDB
0x7fffffef40: 0x00000000 0x00000000 0x00400498 0x00000000
0x7fffffef50: 0x00000000 0x00000000 0x00000000 0x00000000
ldr x0,=0xdead
(gdb)
ldr x1,=0xc0de
(gdb)
stp x0, x1, [sp, #-16]!
(gdb) x/8x $sp
0x7fffffef30: 0x0000dead 0x00000000 0x0000c0de 0x00000000
0x7fffffef40: 0x00000000 0x00000000 0x00400498 0x00000000
ldr xzr, [sp], #16
(gdb) x/8x $sp
0x7fffffef40: 0x00000000 0x00000000 0x00400498 0x00000000
0x7fffffef50: 0x00000000 0x00000000 0x00000000 0x00000000
还要记住,在ARMv8中,堆栈应该是四字对齐或SP mod 16 = 0。 所以你可以使用XZR中的一个&#34;推送&#34;或者&#34;弹出&#34;配对寄存器。
stp x1, xzr, [sp, #-16]!
ldp x10, xzr, [sp], #16
答案 4 :(得分:-1)
<强> TL; DR 强>
将64位字面值加载到寄存器中需要多条指令,但只使用zxr将一条指令设置为0。因此代码更短更快。
要将文字移动到寄存器,您可以使用MOVL指令,请参阅臂参考:
MOVL伪指令
使用以下任一方式加载寄存器:
A 32-bit or 64-bit immediate value. Any address.
MOVL生成两条或四条指令...... MOV,MOVK对。
因此,将文字加载到寄存器中是一个多步骤的过程。如果您只想清除寄存器,那么他们就有了快捷方式。 zxr是一个伪寄存器,它总是读取零,这是一个你需要的公共值,并且可以在一条指令中将寄存器移到寄存器。
在Microchip组装中,它们具有类似的概念。要将寄存器设置为文字,您可以执行以下操作:
MOVLW 10 (Move 10 to the working register)
MOVWF 0x1234 (Move the working register to address 0x1234)
但要设置为零,他们会有指令:
CLRF 0x1234 (Set 0x1234 to zero)