assembly - 在SSE中组合前缀

标签 assembly x86 sse machine-code prefixes

在SSE中,前缀066h(操作数大小覆盖)0F2H(REPNE)和0F3h(REPE)是操作码的一部分。

在非SSE中,066h在32位(或64位)和16位操作之间切换。 0F2h0F3h用于字符串操作。可以将它们组合在一起,以便066h0F2h(或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

但是,我也知道CSDS段覆盖前缀具有新的功能,作为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/

相关文章:

组件(TASM): print the sum of certain bits in bytes

assembly - 我怎样才能将两个数字相加,每个数字有 12 个字节?

c - 简单 C Bootstrap /内核的问题

windows - 哪些版本的 Windows 支持/需要哪些 CPU 多媒体扩展? (如何检查 SSE 或 AVX 是否完全可用?)

c++ - 按列主要顺序重新排序 3D vector 三元组很慢

assembly - Windows 使用 intel 汇编而 *nix 使用 at&t 是真的吗?

assembly - 使用时间和对齐 NASM 指令在复位向量指向的地址中放置一条指令

组装多次推送不考虑推送列表顺序

assembly - 切换到保护模式并进行远跳转后出错

c++ - NEON vector 数据类型的别名