1

这很简单,但我还没有弄清楚。

这个问题是关于一个程序集 mmx,但它是纯粹的逻辑。

想象以下场景:

MM0: 04 03 02 01 04 03 02 01  <-- input  
MM1: 02 02 02 02 02 02 02 02  
MM2: 04 03 02 01 04 03 02 01  <-- copy of input

after pcmpgtw MM0, MM1

MM0: FF FF 00 00 FF FF 00 00  <-- words where MM0 is greater than MM1 (comparing words)  
MM1: 02 02 02 02 02 02 02 02  
MM2: 04 03 02 01 04 03 02 01

after pand MM0, MM2  

MM0: 04 03 00 00 04 03 00 00  <-- almost there...
MM1: 02 02 02 02 02 02 02 02  
MM2: 04 03 02 01 04 03 02 01  

我想知道用 02 填充 MM0 的零。我想我必须在步骤 2 中反转 MM0 寄存器,将 FF 更改为 00,将 00 更改为 FF,然后执行 a and 到 MM1,最后 a or 合并二。

如果我能够得到:

MM3: 00 00 FF FF 00 00 FF FF

then, pand MM2, MM3

MM1: 04 03 00 00 04 03 00 00  
MM2: 00 00 02 02 00 00 02 02

finally por MM0, MM1 would give me the desired outcome:

MM0: 04 03 02 02 04 03 02 02  <-- Aha!

总结一下,我怎样才能将 MM3 寄存器设为 00 00 FF FF 00 00 FF ?如何反转位,证明我在 MMX 寄存器中只有 AND、OR、XOR 和 NAND 指令?

非常感谢任何答案。谢谢。

4

2 回答 2

1

所以你有一个mask = 0xFFFF0000FFFF0000;then:

all_ones = 0xFFFFFFFFFFFFFFFF;

inverted_mask = mask XOR all_ones;

合并 M0 和 M1 是:

M0 = M0 AND mask;
M1 = M1 AND inverted_mask;
M0 = M0 OR M1;

这会在原地编辑 M0 和 M1,因此它们的值被破坏。如果要保留 M1,则需要将中间结果存储到临时变量/寄存器/内存中:

M0 = M0 AND mask;
TEMP = M1 AND inverted_mask;
M0 = M0 OR TEMP;
于 2010-01-26T02:05:27.540 回答
1

您还可以使用 pcmpgtw 生成掩码并交换参数的顺序。这样你就可以保存一个寄存器:

MM0: 04 03 02 01 04 03 02 01  <-- input  
MM1: 02 02 02 02 02 02 02 02  
MM2: 04 03 02 01 04 03 02 01  <-- copy of input


pcmpgtw MM0, MM1    ; MM0 = FF FF 00 00 FF FF 00 00 
pcmpgtw MM1, MM2    ; MM1 = 00 00 FF FF 00 00 FF FF

您可能必须复制 MM1 参数,因为它会在掩码生成期间被破坏,但这通常比加载/生成 64 位常量更快。

另一种方法是使用 PNAND:

pcmpgtw MM0, MM1    ; MM0 = FF FF 00 00 FF FF 00 00 

pand    MM2, MM0    ; leave bytes with FF intact 
pnand   MM1, MM0    ; leave bytes with 00 intact 
por     MM1, MM2    ; combine the results.
于 2010-02-24T15:53:32.637 回答