装配掩码逻辑问题

时间:2010-01-26 01:22:14

标签: assembly logic boolean mask mmx

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

这个问题是关于程序集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到MM1,最后是a或者将这两者合并。

如果我能得到:

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指令?

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

2 个答案:

答案 0 :(得分:1)

所以你有mask = 0xFFFF0000FFFF0000;然后:

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;

答案 1 :(得分: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.