Nat*_*man 7 x86 assembly sse prefixes
在SSE中,前缀066h(操作数大小覆盖)0F2H(REPNE)和0F3h(REPE)是操作码的一部分.
在066h32位(或64位)和16位操作之间的非SSE 切换中. 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 的文档中有所规定,但许多情况并未涵盖在内)。并且某些组合可能会保留以备将来使用。
我天真的假设通常是额外的前缀是无操作的,但不能保证。考虑到例如一些优化手册推荐多字节NOP(规范90h),这似乎是合理的66h,例如:
db 66h, 90h; 2-byte NOP
db 66h, 66h, 90h; 3-byte NOP
db 66h, 66h, 66h, 90h; 4-byte NOP
Run Code Online (Sandbox Code Playgroud)
但是,我也知道,当应用于条件跳转指令时CS,DS段覆盖前缀具有作为 SSE2 分支提示前缀(预测分支采用 = 3Eh=DS覆盖;预测分支未采用 = 2Eh=CS覆盖)的新功能。
无论如何,我看了你上面的例子,总是设置XMM1为 all0和XMM7all 0FFhby
pxor xmm1, xmm1 ; xmm1 <- 0s
pcmpeqw xmm7, xmm7 ; xmm7 <- FFs
Run Code Online (Sandbox Code Playgroud)
然后是有问题的代码,带有xmm1, xmm7参数。我观察到的(Win64 系统和 Intel T7300 Core 2 Duo 上的 32 位代码)是:
1)addsd通过添加66h前缀没有观察到变化
db 66h
addsd xmm1, xmm7 ;total sequence = 66 F2 0F 58 CF
Run Code Online (Sandbox Code Playgroud)
2)addss通过添加0F2h前缀没有观察到变化
db 0f2h
addss xmm1,xmm7 ;total sequence = F2 F3 0F 58 CF
Run Code Online (Sandbox Code Playgroud)
3)但是,我通过前缀中观察到的变化addpd由0F2h:
db 0f2h
addpd xmm1, xmm7 ;total sequence = F2 66 0F 58 CF
Run Code Online (Sandbox Code Playgroud)
在这种情况下,XMM1 中的结果0000000000000000FFFFFFFFFFFFFFFFh不是FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFh。
所以我的结论是,不应做出任何假设并期望“未定义”的行为。不过,如果您能在 Agner 雾的手册中找到一些线索,我不会感到惊讶。