📄 cmemory.cpp
字号:
#include <windows.h>
#include "CMemory.h"
#include "CMMX.h"
//MMX 内存拷贝
//注意:count 为 64 的倍数
void Qmemcpy_mmx_64(void *dst, void *src, int count)
{
_asm
{
mov edi,dst;
mov esi,src;
mov ecx, count; //要拷贝多少个块
lea esi, [esi+ecx];
lea edi, [edi+ecx];
neg ecx; //eax=-eax;
loopwrite:
movq mm0,[esi+ecx]; //放入mm0
movq mm1,[esi+ecx+8]; //放入mm0
movq mm2,[esi+ecx+16]; //放入mm0
movq mm3,[esi+ecx+24]; //放入mm0
movq mm4,[esi+ecx+32]; //放入mm0
movq mm5,[esi+ecx+40]; //放入mm0
movq mm6,[esi+ecx+48]; //放入mm0
movq mm7,[esi+ecx+56]; //放入mm0
movq [edi+ecx],mm0;
movq [edi+ecx+8],mm1; //放入mm0
movq [edi+ecx+16],mm2; //放入mm0
movq [edi+ecx+24],mm3; //放入mm0
movq [edi+ecx+32],mm4;
movq [edi+ecx+40],mm5; //放入mm0
movq [edi+ecx+48],mm6; //放入mm0
movq [edi+ecx+56],mm7; //放入mm0
add ecx, 64; //一次16个字节,当然加16
jnz loopwrite; //如果不等于0就循环
emms; //清空
}
}
//注意:count 为 32 的倍数
void Qmemcpy_mmx_32(void *dst, void *src, int count)
{
_asm
{
mov edi,dst;
mov esi,src;
mov ecx, count; //要拷贝多少个块
lea esi, [esi+ecx];
lea edi, [edi+ecx];
neg ecx; //eax=-eax;
loopwrite:
movq mm0,[esi+ecx]; //放入mm0
movq mm1,[esi+ecx+8]; //放入mm0
movq mm2,[esi+ecx+16]; //放入mm0
movq mm3,[esi+ecx+24]; //放入mm0
movq [edi+ecx],mm0;
movq [edi+ecx+8],mm1; //放入mm0
movq [edi+ecx+16],mm2; //放入mm0
movq [edi+ecx+24],mm3; //放入mm0
add ecx, 32; //一次16个字节,当然加16
jnz loopwrite; //如果不等于0就循环
emms; //清空
}
}
//注意:count 为 16 的倍数
void Qmemcpy_mmx_16(void *dst, void *src, int count)
{
_asm
{
mov edi,dst;
mov esi,src;
mov ecx, count; //要拷贝多少个块
lea esi, [esi+ecx];
lea edi, [edi+ecx];
neg ecx; //eax=-eax;
loopwrite:
movd mm0,dword ptr [esi+ecx]; //放入mm0
movd mm1,dword ptr [esi+ecx+4]; //放入mm0
movd mm2,dword ptr [esi+ecx+8]; //放入mm0
movd mm3,dword ptr [esi+ecx+12]; //放入mm0
movd dword ptr[edi+ecx],mm0;
movd dword ptr [edi+ecx+4],mm1; //放入mm0
movd dword ptr [edi+ecx+8],mm2; //放入mm0
movd dword ptr [edi+ecx+12],mm3; //放入mm0
add ecx, 16; //一次16个字节,当然加16
jnz loopwrite; //如果不等于0就循环
emms; //清空
}
}
//注意:count 为 8 的倍数
void Qmemcpy_mmx_8(void *dst, void *src, int count)
{
int n=count;
_asm
{
mov edi,dst;
mov esi,src;
mov ecx, n; //要拷贝多少个块
lea esi, [esi+ecx];
lea edi, [edi+ecx];
neg ecx; //eax=-eax;
loopwrite:
movd mm0,dword ptr [esi+ecx]; //放入mm0
movd mm1,dword ptr [esi+ecx+4]; //放入mm0
movd dword ptr[edi+ecx],mm0;
movd dword ptr [edi+ecx+4],mm1; //放入mm0
add ecx, 8; //一次四个字节,当然加4
jnz loopwrite; //如果不等于0就循环
emms; //清空
}
}
//MMX内存重置
void Qmemset_mmx_32(void *dst, int c, int count)
{
//QMemset MMX版本
//注意 count 应被 32 整除
__asm
{
movq mm0, c //因为Int是32位的,直接用movd读入
//以下将 mm0重置成64位
punpcklbw mm0, mm0 //将 8 Byte 转 4 WORD //|cccccccc00000000|
punpcklwd mm0, mm0 //将 4 Word 转 2 DWORD//|c0c0c0c0c0c0c0c0|
punpckldq mm0, mm0 //将 2DWORD 转 1 QWORD //|cccccccccccccccc|0000000000000000|
mov edi, dst
mov ecx, count
lea edi, [edi + ecx]
neg ecx //ecx=-ecx;
movq mm1, mm0 //将mm1 置0
movq mm2, mm0 //将mm2 置0
movq mm3, mm0 //将mm3 置0
movq mm4, mm0 //将mm4 置0
loopwrite:
movq qword ptr[edi+ecx], mm0
movq qword ptr[edi+ecx+8 ], mm1
movq qword ptr[edi+ecx+16], mm2
movq qword ptr[edi+ecx+24], mm3
add ecx, 32;
jnz loopwrite;
emms;
}
}
void Qmemset_mmx_16(void *dst, int c, int count)
{
//QMemset MMX版本
//注意 count 应被 32 整除
__asm
{
movq mm0, c //因为Int是32位的,直接用movd读入
//以下将 mm0重置成64位
punpcklbw mm0, mm0 //将 8 Byte 转 4 WORD //|cccccccc00000000|
punpcklwd mm0, mm0 //将 4 Word 转 2 DWORD//|c0c0c0c0c0c0c0c0|
punpckldq mm0, mm0 //将 2DWORD 转 1 QWORD //|cccccccccccccccc|0000000000000000|
mov edi, dst
mov ecx, count
lea edi, [edi + ecx]
neg ecx //ecx=-ecx;
movq mm1, mm0 //将mm1 置0
movq mm2, mm0 //将mm2 置0
loopwrite:
movq qword ptr[edi+ecx], mm0
movq qword ptr[edi+ecx+8 ], mm1
add ecx, 16;
jnz loopwrite;
emms;
}
}
//=================================
//------------接口部分-------------
//=================================
//===================================================
//函数:void Qmemcpy(void *dest, void *src, int count)
//功能:将Src的Count个字节拷贝到Dest
//===================================================
void Qmemcpy(void *dest, void *src, int count)
{
bool IsMMX=CheckMMX();
if (IsMMX==true&&(count%2==0)&&count>=8)
{
if (count%64==0)Qmemcpy_mmx_64(dest,src,count);
else if (count%32==0)Qmemcpy_mmx_32(dest,src,count);
else if (count%16==0) Qmemcpy_mmx_16(dest,src,count);
else if(count%8==0)Qmemcpy_mmx_8(dest,src,count);
else goto _cmemcpy;
}
else
{
_cmemcpy:
int i;
BYTE *d=(BYTE *)dest;
const BYTE *s=(const BYTE *)src;
for (i=0;i<count;i++,++d,++s)
*d=*s;
}
}
void Qmemset(void *dst, int c, int count)
{
if (c==0) //特殊的时候
{
ZeroMemory(dst,count); //用Windows提供的宏
}
else
{
bool IsMMX=CheckMMX(); //查找 MMX
if (IsMMX==true&&(count%2==0)&&count>=16)
{
if (count%32==0) Qmemset_mmx_32(dst,c,count);
else if (count%16==0) Qmemset_mmx_16(dst,c,count);
else goto _cmemset;
}
else _cmemset:FillMemory(dst,count,c); //用Windows宏
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -