在SSE中,前缀066h
(操作数大小覆盖)0F2H
(REPNE)和0F3h
(REPE)是操作码的一部分。
在非SSE中,066h
在32位(或64位)和16位操作之间切换。 0F2h
和0F3h
用于字符串操作。可以将它们组合在一起,以便066h
和0F2h
(或0F3h
)可以在同一指令中使用,因为这很有意义。 SSE指令中的行为是什么?例如,我们有(现在忽略mod/rm):
0f 58 addps
66 0f 58 addpd
f2 0f 58 addsd
f3 0f 58 addss
但是,这是什么?
66 f2 0f 58
那又如何呢?
f2 66 0f 58
更不用说以下具有两个冲突的REP前缀的情况:
f2 f3 0f 58
这些是什么规范?
最佳答案
我不记得曾见过任何关于在随机组合随机前缀的情况下期望得到的规范,因此我猜想CPU行为可能是“未定义”的,并且可能是特定于CPU的。 (很明显,某些事情在例如Intel的文档中已指定,但很多情况未涵盖在内)。并且某些组合可能会保留以供将来使用。
我幼稚的假设通常是,其他前缀是no-ops,但不能保证。考虑到例如一些优化手册通过在前缀NOP
之前推荐多字节的90h
(规范地为66h
),例如:
db 66h, 90h; 2-byte NOP
db 66h, 66h, 90h; 3-byte NOP
db 66h, 66h, 66h, 90h; 4-byte NOP
但是,我也知道
CS
和DS
段覆盖前缀具有新的功能,作为SSE2分支提示前缀(应用于条件跳转指令时,用作预测分支= 3Eh
= DS
覆盖;预测未采用= 2Eh
= CS
覆盖)。无论如何,我看了上面的示例,始终将
XMM1
设置为所有0
,并将XMM7
设置为所有0FFh
,pxor xmm1, xmm1 ; xmm1 <- 0s
pcmpeqw xmm7, xmm7 ; xmm7 <- FFs
然后是带有
xmm1, xmm7
参数的相关代码。我观察到的(在Win64系统和Intel T7300 Core 2 Duo上为32位代码)是:1)通过添加
addsd
前缀未观察到66h
的更改db 66h
addsd xmm1, xmm7 ;total sequence = 66 F2 0F 58 CF
2)通过添加
addss
前缀未观察到0F2h
的变化db 0f2h
addss xmm1,xmm7 ;total sequence = F2 F3 0F 58 CF
3)但是,我通过在
addpd
前面加上0F2h
来观察到了变化:db 0f2h
addpd xmm1, xmm7 ;total sequence = F2 66 0F 58 CF
在这种情况下,XMM1中的结果是
0000000000000000FFFFFFFFFFFFFFFFh
而不是FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFh
。因此,我的结论是,不应做出任何假设并且不要期望的“未定义”行为。但是,如果您可以在Agner fog的manuals中找到一些线索,我也不会感到惊讶。
关于assembly - 在SSE中组合前缀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2404364/