Pergunta

No SSE os prefixos 066h (substituição do tamanho do operando) 0F2H (REPNE) e 0F3h (REPE) fazem parte do opcode.

Em não-SSE 066h alterna entre operação de 32 bits (ou 64 bits) e 16 bits. 0F2h e 0F3h são usados ​​para operações de string.Eles podem ser combinados para que 066h e 0F2h (ou 0F3h) pode ser usado na mesma instrução, porque isso é significativo.Qual é o comportamento em uma instrução SSE?Por exemplo, temos (ignorando mod/rm por enquanto):

0f 58 --> addps

66 0f 58 --> addpd

f2 0f 58 --> addsd

f3 0f 58 --> addss

Mas o que é isso?

66 f2 0f 58

E que tal?

f2 66 0f 58

Sem mencionar o seguinte, que possui dois prefixos REP conflitantes:

f2 f3 0f 58

Qual é a especificação para estes?

Foi útil?

Solução

Não me lembro de ter visto nenhuma especificação sobre o que você deveria esperar no caso de combinação descontrolada de prefixos aleatórios, então acho que o comportamento da CPU pode ser "indefinido" e possivelmente específico da CPU.(Claramente, algumas coisas são especificadas, por ex.Documentos da Intel, mas muitos casos não são cobertos).E algumas combinações podem ser reservadas para uso futuro.

Minhas suposições ingênuas geralmente seriam de que prefixos adicionais não funcionariam, mas não há garantia.Isso parece razoável, dado que, e.alguns manuais de otimização recomendam multi-byte NOP (canonicamente 90h) prefixando com 66h, por exemplo.:

db 66h, 90h; 2-byte NOP
db 66h, 66h, 90h; 3-byte NOP
db 66h, 66h, 66h, 90h; 4-byte NOP

Contudo, também sei que CS e DS prefixos de substituição de segmento adquiriram novas funções como prefixos de dica de ramificação SSE2 (prever ramificação tomada = 3Eh = DS sobrepor;prever ramo não tomado = 2Eh = CS override) quando aplicado a instruções de salto condicional.

Enfim, olhei seus exemplos acima, sempre definindo XMM1 para todos 0 e XMM7 para todos 0FFh por

pxor xmm1, xmm1    ; xmm1 <- 0s
pcmpeqw xmm7, xmm7 ; xmm7 <- FFs 

e então o código em questão, com xmm1, xmm7 argumentos.O que observei (código de 32 bits no sistema Win64 e Intel T7300 Core 2 Duo) foi:

1) nenhuma mudança observada para addsd adicionando 66h prefixo

db 66h 
addsd xmm1, xmm7 ;total sequence = 66 F2 0F 58 CF     

2) nenhuma mudança observada para addss adicionando 0F2h prefixo

db 0f2h     
addss xmm1,xmm7 ;total sequence = F2 F3 0F 58 CF

3) Porém, observei uma mudança ao prefixar addpd por 0F2h:

db 0f2h    
addpd xmm1, xmm7 ;total sequence = F2 66 0F 58 CF

Neste caso, o resultado em XMM1 foi 0000000000000000FFFFFFFFFFFFFFFFh em vez de FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFh.

Então minha conclusão é que não se deve fazer suposições e esperar um comportamento "indefinido".Eu não ficaria surpreso, entretanto, se você pudesse encontrar algumas pistas no nevoeiro de Agner. manuais.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top