MMX指令集在C++中的使用
2010-01-23 20:32:30 来源:WEB开发网2、使用MMX指令集的注意事项
由于在CPU内部,FPU寄存器和MMX寄存器是同一组寄存器,所以在同时引用上面寄存器时要注意正确的状态转换,具体做法以后在探讨。你只要先记住不能简单的混合以上两种指令集即可。
每次调用之前要先检测cpu是否支持MMX指令集,以免发生异常。具体做法看下列示例:
mov EAX, 1 ; request for feature flags
这段代码来自Intel的参考手册,所以你可以放心的使用。
CPUID ; 0Fh, 0A2h CPUID instruction
test EDX, 00800000h ; Is IA MMX technology bit (Bit 23 of EDX)
; in feature flags set?
jnz MMX_Technology_Found
3、下面用一段示例代码来说明一下怎样用MMX指令
__int8 i8_a[2][16]; //字节操作数,两组,每组16个
__int16 i16_a[8]; //字操作数
__int32 i32_a[4];
__int64 i64_a[2];
i64_a[0]=0;
i64_a[1]=0;
i32_a[0]=1000;
i32_a[1]=1000;
i32_a[2]=3;
i32_a[3]=4;
i16_a[0]=10;
i16_a[1]=20;
i16_a[2]=30;
i16_a[3]=40;
i16_a[4]=50;
i16_a[5]=60;
i16_a[6]=70;
i16_a[7]=80;
i8_a[0][0]=1;
i8_a[0][1]=1;
i8_a[0][2]=1;
i8_a[0][3]=1;
i8_a[0][4]=1;
i8_a[0][5]=1;
i8_a[0][6]=1;
i8_a[0][7]=1;
i8_a[0][8]=1;
i8_a[0][9]=1;
i8_a[0][10]=1;
i8_a[0][11]=1;
i8_a[0][12]=1;
i8_a[0][13]=1;
i8_a[0][14]=1;
i8_a[0][15]=1;
i8_a[1][0]=2;
i8_a[1][1]=2;
i8_a[1][2]=2;
i8_a[1][3]=2;
i8_a[1][4]=2;
i8_a[1][5]=2;
i8_a[1][6]=2;
i8_a[1][7]=2;
i8_a[1][8]=2;
i8_a[1][9]=2;
i8_a[1][10]=2;
i8_a[1][11]=2;
i8_a[1][12]=2;
i8_a[1][13]=2;
i8_a[1][14]=2;
i8_a[1][15]=2;
__asm{
movq mm1,[i64_a]
movq mm2,[i64_a]
movq mm2, [i32_a+8]
psubd mm2, [i32_a]
movq [i32_a],mm2
movq mm1,[i16_a]
paddsw mm1,[i16_a+8]
movq [i16_a],mm1
movq mm1,[i8_a]
movq mm2,[i8_a+8]
paddb mm1,[i8_a+16]
paddb mm2,[i8_a+24]
movq [i8_a],mm1
movq [i8_a+8],mm2
emms //最后清除MMX状态寄存器,正确返回给系统
}
你可以通过设置断点,和watch的方法来观察寄存器以及变量的变化情况,这里只是引用了一部分的指令,那么最引人注意的是对i16_a、i8_a、以及i32_a数组的操作,我是随便对他们进行了算术运算,大家可以看到我加两组字节数组数据时只用了两条加指令,这是普通的指令集望尘莫及的。这就是单指令,多数据的魅力。同时你也可以看到对64位整数的操作也简单多了。但是要注意的是,MMX指令集里好像没有提供除法操作。所以你需借助算法来实现。另外要补充的是MMX寄存器是从MM0-MM7命名的一组64位寄存器。
本文配套源码
更多精彩
赞助商链接