[英]Why might one use the xzr register instead of the literal 0 on ARMv8?
我認為mov x8, xzr
vs mov x8, #0
比較是一個紅色的鯡魚。
正如@ old_timer的回答所示,沒有編碼增益,很可能(雖然我沒有檢查)很少或沒有管道性能增益。
然而, xzr
給我們的是 - 除了xzr
的答案之外的虛擬寄存器 - 是訪問零值操作數而無需加載和占用實際寄存器 。 這具有一個較少指令的雙重好處,並且還有一個寄存器可用於保存“真實”數據。
我認為這是一個重要的特征, OP中提到的原始“來自ARM的一些內容”忽略了指出。
這就是我的意思是mov x8, xzr
vs mov x8, #0
是一個紅色的鯡魚。 如果我們將x8
零以便隨后修改它,那么使用xzr
或#0
是非常隨意的(盡管我傾向於贊成#0
更為明顯)。 但是,如果我們歸零x8
,以提供一個零操作數后續指令純粹,那么,我們會更好用-如果允許- xzr
而不是x8
作為該指令的操作數,而不是零x8
的。
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,如總是零注冊的東西,讓我們只是為了好玩。
這兩條指令應該是相同的 - 在效果和預期性能方面。
它們實際上都是更多通用指令的別名 。
mov x8, 0
orr x8, xzr, 0
被編碼為orr x8, xzr, 0
mov x8, xzr
編碼為orr x8, xzr, xzr
別名很有用,因為它們使ASM更具可讀性。
第二種編碼說明了為什么使用零寄存器xzr
會很有用。 因為我們知道xzr總是為零,所以我們可以重用mov
的orr
指令。 沒有它, mov
將需要不同的編碼,因此會浪費編碼空間。
這個答案對OP來說並非“四肢着地”。
XZR可用於丟棄結果; 例如,“ldr xzr,[sp],16”。 見下面的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中的一個“推”或“彈出”對寄存器。
stp x1, xzr, [sp, #-16]!
ldp x10, xzr, [sp], #16
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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.