Assembly SSE中前缀的组合
在SSE中,前缀Assembly SSE中前缀的组合,assembly,x86,sse,machine-code,prefixes,Assembly,X86,Sse,Machine Code,Prefixes,在SSE中,前缀066h(操作数大小覆盖)0F2H(REPNE)和0F3h(REPE)是操作码的一部分 在非SSE模式下,066h在32位(或64位)和16位操作之间切换0F2h和0F3h用于字符串操作。它们可以组合在一起,以便在同一指令中使用066h和0F2h(或0F3h),因为这是有意义的。SSE指令中的行为是什么?例如,我们有(现在忽略mod/rm): 但这是什么 66 f2 0f 58 那你呢 f2 66 0f 58 更不用说有两个相互冲突的REP前缀: f2 f3 0f 58 这
066h
(操作数大小覆盖)0F2H
(REPNE)和0F3h
(REPE)是操作码的一部分
在非SSE模式下,066h在32位(或64位)和16位操作之间切换0F2h
和0F3h
用于字符串操作。它们可以组合在一起,以便在同一指令中使用066h
和0F2h
(或0F3h
),因为这是有意义的。SSE指令中的行为是什么?例如,我们有(现在忽略mod/rm):
但这是什么
66 f2 0f 58
那你呢
f2 66 0f 58
更不用说有两个相互冲突的REP前缀:
f2 f3 0f 58
这些的规格是什么?我不记得在大量组合随机前缀的情况下,您应该看到什么规格,所以我猜CPU行为可能是“未定义的”,可能是特定于CPU的。(很明显,有些事情在英特尔的文档中有详细说明,但很多情况下并未涉及)。一些组合可能保留供将来使用 我天真的假设通常是,额外的前缀将不会是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分支提示前缀(predict branch take=3Eh
=DS
覆盖;predict branch not take=2Eh
=CS
覆盖)
不管怎样,我看了上面的例子,总是将XMM1
设置为all0
和XMM7
设置为all0FFh
pxor xmm1, xmm1 ; xmm1 <- 0s
pcmpeqw xmm7, xmm7 ; xmm7 <- FFs
2) 通过添加0F2h
前缀,未观察到addss
的任何变化
db 66h
addsd xmm1, xmm7 ;total sequence = 66 F2 0F 58 CF
db 0f2h
addss xmm1,xmm7 ;total sequence = F2 F3 0F 58 CF
3) 但是,我通过在0F2h
前面加前缀addpd
观察到了一个变化:
db 0f2h
addpd xmm1, xmm7 ;total sequence = F2 66 0F 58 CF
在这种情况下,XMM1中的结果是000000000000000ffffffffffffffffffffh
,而不是ffffffffffffffffffffffffh
因此我的结论是,一个人不应该做出任何假设,期待“未定义”的行为。然而,如果你能在Agner fog的书中找到一些线索,我也不会感到惊讶。英特尔SDM第二卷手册(指令集参考)将这些称为强制前缀。将它们视为操作码的一部分
但是是的,它们是前缀,可以在实际转义字节+操作码之前与其他前缀混合。事实上,REX前缀必须跟在其他前缀后面
与往常一样,使用来自同一组的多个冲突前缀进行解码时,最后一个前缀在当前Intel硬件上具有优先权。我认为英特尔手册上说,这样做会导致不可预测的行为,因此无法保证或证明未来。这不是一件有意义的事情;如果出于对齐的原因,希望填充一条指令以使其更长,我认为将同一前缀重复几次是安全的
SSE指令使用ModR/M格式,前面有0FH
前缀字节。通常,操作不会重复以提供两个
方向(即,单独加载和存储变量)
以下三个表(表B-22、B-23和B-24)显示了
SSE SIMD浮点、SIMD整数、,
以及可缓存性和内存排序指令一些
SSE指令要求将强制性前缀(66H、F2H、F3H)作为
双字节操作码。表中包含必填前缀。
而且 2.1.2操作码 主操作码的长度可以是1、2或3字节。附加的3位操作码字段有时在 ModR/M字节。可以在主操作码中定义较小的字段。这些字段定义操作方向、位移大小、寄存器编码、条件代码或符号扩展。对用户使用的字段进行编码 操作码因操作类别而异 通用指令和SIMD指令的两字节操作码格式由以下内容之一组成:
- 一个转义操作码字节
作为主操作码和第二个操作码字节0FH
- 强制前缀(
、66H
或F2H
)、转义操作码字节和第二个操作码字节(与前一个相同) 子弹)F3H
F3 0F E6
第一个字节是强制前缀(不是
视为重复前缀)。
通用指令和SIMD指令的三字节操作码格式由以下之一组成:
- 一个转义操作码字节0FH作为主操作码,再加上两个附加操作码字节
- 一个强制前缀(66H、F2H或F3H)、一个转义操作码字节,再加上两个额外的操作码字节(与 上一个项目)
f3 0f 58 ADDSS不是ADDPD吗?显然,在最后一种情况下,
0F2h
优先于066h
,并将指令转换为addsd
,这就是为什么只编写了一个块。这是一个假设,是的。然而,我认为如果有人想依靠这种行为,那是个坏主意。
db 0f2h
addpd xmm1, xmm7 ;total sequence = F2 66 0F 58 CF