为什么可以在ARMv8上使用xzr寄存器而不是文字0?

OMG*_*chy 8 assembly arm armv8

我正在阅读ARM发布的SVE白皮书,并发现了令我印象深刻的东西(在非SVE示例中):

mov x8, xzr
Run Code Online (Sandbox Code Playgroud)

我不知道这个xzr寄存器是什么,所以我查了一下,发现ARM的一些内容,说它在很多情况下都是零的同义词.

所以看起来x8它被初始化为零,这是有道理的,因为它在循环之前执行,x8用作循环计数器.

我不明白的是,为什么不使用文字0而不是xzr?例如:

mov x8, 0
Run Code Online (Sandbox Code Playgroud)

总而言之,我的问题是:为什么可以使用xzr寄存器而不是文字0

old*_*mer 7

mov x8,xzr
mov x8,#0
mov x8,0
Run Code Online (Sandbox Code Playgroud)

产生

0000000000000000 <.text>:
   0:   aa1f03e8    mov x8, xzr
   4:   d2800008    mov x8, #0x0                    // #0
   8:   d2800008    mov x8, #0x0                    // #0
Run Code Online (Sandbox Code Playgroud)

除了允许立即不带井号之外,没有什么真正令人惊讶的。这不是指令大小问题(同样毫不奇怪,对于 x86,例如 xor rax,rax 比 mov rax,0 便宜),也许存在管道性能增益(尽管普遍认为指令从开始到结束需要多个时钟) 。

最有可能的是,这是个人喜好的事情,我们有这个很酷的 mips,就像总是零寄存器的东西,让我们只是为了好玩而使用它。


Jer*_*emy 6

我觉得 mov x8, xzr vs mov x8, #0比较有点让人讨厌。

如@old_timer的答案所示,没有编码增益可言,并且很有可能(尽管我承认没有检查过)管道性能增益很小或没有。

是什么xzr给了我们,但是-除了虚拟寄存器按@ InfinitelyManic的答案-是获得一个零值操作数,而无需负载并占据一个真正的寄存器。这具有双重好处:减少一条指令,再增加一个寄存器来保存“真实”数据。

我认为这是OP中提到的原始“来自ARM的某些内容”的重要特征忽略指出的。

这就是我mov x8, xzrmov x8, #0红色鲱鱼的意思。如果我们x8打算将其修改然后归零,则使用xzr#0会相当随意(尽管我倾向于倾向于#0更明显)。但是,如果我们x8纯粹是为了将零操作数提供给后续指令而置零,那么最好使用-在允许的情况下- xzr代替指令中x8的操作数,并且根本不要置零。x8