C++使用汇编获取CPU信息,学到的是思路

首先 贴一段通过读取注册表得到CPU商标信息的代码

	HKEY hKey;
	TCHAR CPUInfo[MAX_PATH]={0};
	TCHAR SubKey[MAX_PATH]={0};
	lstrcpy(SubKey,_T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0\0"));
	if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,SubKey,0L,KEY_ALL_ACCESS,&hKey) == ERROR_SUCCESS)
	{
		DWORD dwType;
		DWORD dwSize=200;
		RegQueryValueEx(hKey,_T("ProcessorNameString"),NULL,&dwType,(BYTE *)CPUInfo,&dwSize);
		RegCloseKey(hKey);	
	}


然后贴一段使用汇编获取CPU信息的代码,利用的是cpuid的汇编指令,cpuid指令把eax当作传入参数,例如 eax = 0当作传入参数的时候,

寄存器返回的数据会使用eax,ebx,ecx,edx输出,关于更多的cpuid请看百度百科的详细解释;

第一段汇编代码

	char szCPUInfo[64];
	memset(szCPUInfo,0,sizeof(szCPUInfo)); 
	unsigned long ulId = 0x80000002;      //起始地址 0x80000002 - 0x80000004
	unsigned long ulEax,ulEbx,ulEcx,ulEdx;//返回的数据存放在自定义的变量里 每次读取16个字节

	for (int i = 0; i < 3; i++) //循环3次 CPU商标信息长度为48字节 所以要保证char数组长度
	{
		__asm
		{
			pushad
			mov eax,ulId    //传入参数
			cpuid;
			mov ulEax,eax //依次读取
			mov ulEbx,ebx
			mov ulEcx,ecx
			mov ulEdx,edx
			popad
		}
		memcpy(szCPUInfo+16*i+0, &ulEax,4); //赋值数据
		memcpy(szCPUInfo+16*i+4, &ulEbx,4);
		memcpy(szCPUInfo+16*i+8, &ulEcx,4);
		memcpy(szCPUInfo+16*i+12, &ulEdx,4);
		ulId++;
	}


你是不是看着这么多memcpy很不爽呢,代码无错,但是不精炼。能否只用一个memcpy?

 

第二段代码,因为寄存器返回的数据 eax,ebx,ecx,edx在寄存器中是连续存放的,但是在内存中却不是连续的,这个要注意

	char szCPUInfo[64];
	memset(szCPUInfo,0,sizeof(szCPUInfo)); 
	unsigned long ulId = 0x80000002;      //起始地址 0x80000002 - 0x80000003
	unsigned long ulEax[4];                //定义四个数组

	for (int i = 0; i < 3; i++) //循环3次
	{
		__asm
		{
			pushad
			mov eax,ulId    //传入参数
			cpuid;
			mov ulEax[0],eax //依次读取
			mov ulEax[4],ebx
			mov ulEax[8],ecx
			mov ulEax[12],edx
			popad
		}
		memcpy(szCPUInfo+16*i, &ulEax[0],16); //赋值数据
		ulId++;
	}


只用一个memcpy就可以搞定了,那么不用memcpy函数是否可以?

请看第三段大神代码

	char szCPUInfo[64];
	memset(szCPUInfo,0,sizeof(szCPUInfo));
	unsigned long ulId = 0x80000002;

	char *p = szCPUInfo;
	for (int i = 0; i < 3; i++)
	{
		__asm
		{
			pushad
			mov eax,ulId
			cpuid;
			mov esi,p   //把char数组的内存地址传送给esi
			mov [esi+0],eax
			mov [esi+4],ebx
			mov [esi+8],ecx
			mov [esi+12],edx
			popad
		}

		p += 4*4; //指针后移
		ulId++;
	}

第三段代码,很精炼,这几段虽然代码量不大,但是学到的东西却很多,各位细细品味吧!

因为返回的数据是ansi,如果你使用wchar类型,会乱码的、

注:原创版权为 “女孩不哭”大神所有

再贴一个地址http://www.flounder.com/cpuid_explorer2.htm#CPUID(0x80000001

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页