JWW*_*ker 5 macos x86 assembly xcode cpuid
我想使用cpuid指令来识别Intel CPU的功能。我在Kernel.framework中找到了cpuid.h标头,因此我将Kernel.framework添加到了项目中并包含<Kernel/i386/cpuid.h>
在源文件中。那产生了
kern/kern_types.h: No such file or directory
Run Code Online (Sandbox Code Playgroud)
我不明白。但是该函数do_cpuid
(我想使用的函数)是内联定义的,因此我尝试将其复制到源代码中。
static inline void
do_cpuid(uint32_t selector, uint32_t *data)
{
asm("cpuid"
: "=a" (data[0]),
"=b" (data[1]),
"=c" (data[2]),
"=d" (data[3])
: "a"(selector));
}
Run Code Online (Sandbox Code Playgroud)
那给了我错误:
error: can't find a register in class 'BREG' while reloading 'asm'
error: 'asm' operand has impossible constraints
Run Code Online (Sandbox Code Playgroud)
谷歌搜索该错误导致我提出以下问题:在Mac上出现问题:“重新加载asm时,无法在BREG类中找到一个寄存器”
但是,该问题的解决方案是使用dynamic-no-pic选项(GCC_DYNAMIC_NO_PIC
构建设置),Xcode在构建设置上的帮助显示“不适用于共享库(需要与位置无关)。” 我正在建立一个框架,我认为这是一个共享库。那么我该如何做呢?
这个相当神秘的错误消息:
error: can't find a register in class 'BREG' while reloading 'asm'
error: 'asm' operand has impossible constraints
Run Code Online (Sandbox Code Playgroud)
发生的原因是不允许其中一项约束。在这种情况下是这样的EBX
。使用以下命令编译 32 位代码时-fPIC
当使用选项(位置无关代码)EBX
寄存器用于重定位。它不能用作输出或显示为损坏的寄存器。
尽管大多数人建议使用特殊的编译器标志进行编译,但可以通过修改汇编代码来重写该函数以支持x86-64 / IA32和PIC /非 PICEBX
,以保存寄存器本身并在之后恢复。这可以通过如下代码来完成:
#include <inttypes.h>
static inline void
do_cpuid(uint32_t selector, uint32_t *data)
{
__asm__ __volatile__ (
"xchg %%ebx, %k[tempreg]\n\t"
"cpuid\n\t"
"xchg %%ebx, %k[tempreg]\n"
: "=a" (data[0]),
[tempreg]"=&r" (data[1]),
"=c" (data[2]),
"=d" (data[3])
: "a"(selector),
"c"(0));
}
Run Code Online (Sandbox Code Playgroud)
显着的变化是该data[1]
值将在编译器选择的可用寄存器中返回。该=&r
约束告诉编译器,它选择的任何寄存器都不能是任何其他输入寄存器(我们提前用代码破坏了寄存器xchg
)。在代码中,我们EBX
与编译器选择的可用寄存器进行交换。然后我们再把它换回来。完成后将EBX
包含其原始值,并且所选的空闲寄存器将包含返回的内容CPUID
。然后,汇编器模板会将空闲寄存器的内容移至data[1]
.
通过允许编译器选择一个空闲寄存器,我们有效地规避了这个问题。编译器足够聪明,不会使用EBX
如果它被占用,就不会使用它,因为它可能用于可重定位代码。64 位代码EBX
不像 32 位代码那样用于重定位,因此它可能可供使用。
精明的观察者可能已经注意到了xor %%ecx,%%ecx
。这是我独立于该问题所做的更改EBX
。现在,清除被认为是良好的做法ECX
,因为 AMD 制造的某些处理器如果ECX
不为零,可能会返回过时的值。如果您仅针对非 PPC Mac 平台进行开发,则无需进行此更改,因为 Apple 使用不会表现出此类行为的 Intel 处理器。
通常EBX
在 32 位可重定位/PIC 代码中是特殊的,这就是编译器最初抱怨其神秘消息的原因。
归档时间: |
|
查看次数: |
1368 次 |
最近记录: |