如何将获取CPU品牌名的AT&T汇编语法代码转换为Intel语法?
AT&T转Intel语法:CPU品牌名获取代码修正方案
原AT&T语法的CPU品牌名获取代码,在转换为Intel语法时,直接写mov a[0], eax会报错,同时原转换代码还存在数组类型、大小不匹配的问题,以下是修正后的完整实现:
修正后的MSVC环境Intel语法代码
#include <stdio.h> // CPU品牌字符串共48字节:3次CPUID调用,每次返回4个4字节寄存器值 char cpu_brand[48] = {0}; void brandString(int eaxValues) { // 计算当前写入的数组偏移位置 int offset = (eaxValues - 1) * 16; __asm { // 设置CPUID功能号:1→0x80000002,2→0x80000003,3→0x80000004 mov eax, eaxValues add eax, 0x80000001 cpuid // 将寄存器值写入数组,用dword ptr明确操作数大小 mov dword ptr [cpu_brand + offset], eax mov dword ptr [cpu_brand + offset + 4], ebx mov dword ptr [cpu_brand + offset + 8], ecx mov dword ptr [cpu_brand + offset + 12], edx } } void getCpuID() { printf("Brand string is "); brandString(1); brandString(2); brandString(3); printf("%s\n", cpu_brand); } int main(){ getCpuID(); return 0; }
关键修正点
- 数组调整:原代码的数组大小和类型错误,CPU品牌字符串需要48字节空间,定义
char cpu_brand[48] = {0}保证足够空间并初始化。 - Intel汇编内存访问:MSVC的
__asm块中,必须用dword ptr指明操作数是4字节,格式为dword ptr [数组名 + 偏移量],编译器才能正确解析内存操作。 - 简化功能号设置:用
add eax, 0x80000001直接计算CPUID功能号,去掉冗余的if-else分支。 - 无效代码移除:原
getCpuID中的寄存器清零毫无意义,CPUID仅要求调用前设置好eax的功能号。
GCC环境下的Intel语法实现
如果用GCC编译,需要用带约束的内联汇编,编译时加上-masm=intel参数:
#include <stdio.h> char cpu_brand[48] = {0}; void brandString(int eaxValues) { int offset = (eaxValues - 1) * 16; unsigned int eax, ebx, ecx, edx; asm volatile ( "mov eax, %1\n\t" "add eax, 0x80000001\n\t" "cpuid\n\t" "mov %0, eax\n\t" "mov %2, ebx\n\t" "mov %3, ecx\n\t" "mov %4, edx\n\t" : "=r"(eax), "=r"(eaxValues), "=r"(ebx), "=r"(ecx), "=r"(edx) : "1"(eaxValues) : "eax", "ebx", "ecx", "edx" ); // 通过C代码将寄存器值写入数组,避免汇编中直接访问全局变量 *(unsigned int*)(cpu_brand + offset) = eax; *(unsigned int*)(cpu_brand + offset + 4) = ebx; *(unsigned int*)(cpu_brand + offset + 8) = ecx; *(unsigned int*)(cpu_brand + offset + 12) = edx; } void getCpuID() { printf("Brand string is "); brandString(1); brandString(2); brandString(3); printf("%s\n", cpu_brand); } int main(){ getCpuID(); return 0; }
内容的提问来源于stack exchange,提问作者mark pilsur
相关产品推荐
相关产品推荐

