分享
 
 
 

MMX指令集在C++中的使用

王朝vc·作者佚名  2006-01-17
窄屏简体版  字體: |||超大  

MMX指令集在C++中的使用

作者:孙原

下载本文示例源代码

上次在《关于内联汇编的几个技巧》一文中只是简单地介绍了如何在C++中使用内联汇编,这一次先对上一次的文章作一补充,然后介绍如何使用MMX指令。

一、 内联汇编的一般原则:

1、 自由使用通用寄存器;(EAX,EBX,ECX和EDX)

2、 其它寄存器利用堆栈保留,使用,最后恢复;

一般的像下面这样:

__asm{

push ebp

push esp

……….//使用EBP和ESP

pop esp

popebp

}

二、 内联汇编__asm可以单独使用:

例如:__asm mov eax,anyval1

__asm mov ebx,anyval2

三、 函数返回值可以直接放到eax中,可以不理会警告

例如:

int anyfun(……/*anyparm*/)

{

int irtn;//函数返回值

…… //函数语句

__asm mov eax,irtn //代替return irtn;但编译器会发出警告,可以不理它

}

四、 内联汇编不区分大小写,语法同普通汇编

例如:__asm{

mov eax,ebx

MOV EAX,EBX//同上一句

}

注意:C++的变量还是区分大小写的

五、 内联汇编尽量使用__asm或_asm关键字,而不用标准C++的asm关键字(这个是微软说的)

以上只是一些关于内联汇编的补充,我将出一系列围绕内联汇编的文章,下面接着上一次的话题详细一点地讲一下MMX指令的调用

1、 MMX指令集简介:

[数据传输指令]

movq //传输64位整数

movd //传输32位整数

[数据打包转换指令]

PACKSSWB //Pack words into bytes with signed saturation.

PACKSSDW //Pack doublewords into words with signed saturation.

PACKUSWB //Pack words into bytes with unsigned saturation.

PUNPCKHBW //Unpack high-order bytes.

PUNPCKHWD //Unpack high-order words.

PUNPCKHDQ //Unpack high-order doublewords.

PUNPCKLBW //Unpack low-order bytes.

PUNPCKLWD //Unpack low-order words.

PUNPCKLDQ //Unpack low-order doublewords.

注:这一组指令我没有具体用过,不知道是干什么的,请高手赐教!小弟先谢了!

[ 算术指令]

PADDB

PADDW

PADDD

PADDSB

PADDSW

PADDUSB

PADDUSW

PSUBB

PSUBW

PSUBD

PSUBSB

PSUBSW

PSUBUSB

PSUBUSW

PMULHW

PMULLW

PMADDWD

[ 比较指令]

PCMPEQB Compare packed bytes for equal.

PCMPEQW Compare packed words for equal.

PCMPEQD Compare packed doublewords for equal.

PCMPGTB Compare packed signed byte integers for greater than.

PCMPGTW Compare packed signed word integers for greater than.

PCMPGTD Compare packed signed doubleword integers for greater than.

这组指令用于成组比较数据

[ 位逻辑指令]

PAND Bitwise logical AND.

PANDN Bitwise logical AND NOT.

POR Bitwise logical OR.

PXOR Bitwise logical exclusive OR.

这组指令与AND,XOR基本相同,都是按位进行逻辑运算。

[ 移位和循环移位指令]

PSLLW //Shift packed words left logical.

PSLLD //Shift packed doublewords left logical.

PSLLQ //Shift packed quadword left logical.

PSRLW //Shift packed words right logical.

PSRLD //Shift packed doublewords right logical.

PSRLQ //Shift packed quadword right logical.

PSRAW //Shift packed words right arithmetic.

PSRAD //Shift packed doublewords right arithmetic.

[ 状态管理指令]

EMMS //Empty MMX state.

在VC中要求所有的MMX指令调用完毕后都要调用这个指令清空

例如:__asm{

…..MMX 语句

EMMS//清空状态

}

以上是所有的MMX指令,你可以测试使用其中的指令,他的工作原理就是单指令,多数据 2、 使用MMX指令集的注意事项

由于在CPU内部,FPU寄存器和MMX寄存器是同一组寄存器,所以在同时引用上面寄存器时要注意正确的状态转换,具体做法以后在探讨。你只要先记住不能简单的混合以上两种指令集即可。

每次调用之前要先检测cpu是否支持MMX指令集,以免发生异常。具体做法看下列示例:

mov EAX, 1 ; request for feature flags

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

这段代码来自Intel的参考手册,所以你可以放心的使用。

3、 下面用一段示例代码来说明一下怎样用MMX指令

__int8i8_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位寄存器。

孙原

2002.8.27于西安

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有