Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中使用内联程序集检查RFLAGS中的ID标志_C_X86 64_Inline Assembly_Cpuid - Fatal编程技术网

在C中使用内联程序集检查RFLAGS中的ID标志

在C中使用内联程序集检查RFLAGS中的ID标志,c,x86-64,inline-assembly,cpuid,C,X86 64,Inline Assembly,Cpuid,我编写了以下内联程序集来尝试检查ID标志。我知道应该设置它,因为我可以使用cpuid指令,但是当我测试它时,这个函数返回0 \u Bool/*检查cpu是否有可用的cpuid指令*/ cpu\u有\u cpuid(无效){ uint64_t out; asm(“pushfq\n\t” “popq%[out]\n\t” :[out]“=r”(out) :“记忆”); 返回&0x200000; } 有人知道我做错了什么吗?你能帮我吗 如果有帮助,我在没有位掩码的情况下得到的值是582您可以而且应该

我编写了以下内联程序集来尝试检查ID标志。我知道应该设置它,因为我可以使用cpuid指令,但是当我测试它时,这个函数返回0

\u Bool/*检查cpu是否有可用的cpuid指令*/
cpu\u有\u cpuid(无效){
uint64_t out;
asm(“pushfq\n\t”
“popq%[out]\n\t”
:[out]“=r”(out)
:“记忆”);
返回&0x200000;
}
有人知道我做错了什么吗?你能帮我吗


如果有帮助,我在没有位掩码的情况下得到的值是
582

您可以而且应该使用GNU C
#在您自己的代码中包含
,而不是GNU C内联asm。(),包括对CPUID可用性的32位模式检查


x86-64保证了CPUID的可用性;如果代码可能在486或更早版本上运行,则只需检查它。但是486首先不能运行64位代码

代码的实际问题是它没有尝试翻转ID位。显然
0
对于其当前状态来说是正常的。显示在popf/pushf/pop reg之前使用内存目标XOR的标准检测代码(用于32位模式Intel语法,但很容易移植),以查看设置是否为“take”。(然后恢复原始EFLAG,这可能是不必要的。)

对于GNU C内联asm实现,请参见GCC自己的
cpuid.h
(),其中它是在
\ifndef\uuuux86\u64\uuuuu
中的
\uget\ucpuid\umax
块中完成的。它甚至有AT&T与Intel语法的方言替代,因此使用
\include
的代码在使用
-masm=Intel
编译时不会中断

如果您好奇的话,将其移植到x86-64可以让您验证它是否真的有效


另外,在Linux/Mac(x86-64 System V)上推送/弹出是不安全的:您踩到了红色区域。您需要在前后添加$-128,%rsp
子$-128,%rsp
,以避免推送/弹出踩到编译器rsp下方的红色区域,在该区域可能保留本地变量。看


-128
适合imm8,但
+128
不适合,这就是为什么我建议
添加/sub$-128
而不是
添加/sub$128

好的,非常感谢。