gpt4 book ai didi

C 和内联汇编错误

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:28:14 25 4
gpt4 key购买 nike

我在开发 Linux 设备驱动程序时遇到了一个烦人的错误,我已将其简化为下面的用户态代码。

目的是通过cpuid指令读取Processor中的Core数

似乎在第三阶段产生了一个核心转储,我无法解释?

输出:

Phase 1: FYI Proc=0x1ac1010
Phase 2: CPU count=8
Segmentation fault (core dumped)

此代码是为 Linux 4.0.7-2 64 位编写的,使用 gcc 版本 5.1.0 编译

#include <stdio.h>
#include <stdlib.h>

typedef struct {
unsigned long CPU_count;
} PROC;

PROC *Proc=NULL;

unsigned long CPU_count;

unsigned long CPU_Count(void)
{
unsigned long c=0;

__asm__ volatile
(
"movq $0x4, %%rax \n\t"
"xorq %%rcx, %%rcx \n\t"
"cpuid \n\t"
"shr $26, %%rax \n\t"
"and $0x3f, %%rax \n\t"
"inc %%rax \n\t"
"movq %%rax, %0"
: "=m" (c)
:
: "rax", "memory"
);
return(c);
}

int main(int argc, char *argv[])
{
if((Proc=malloc(sizeof(PROC))) != NULL)
{
printf("Phase 1: FYI Proc=%p\n", Proc);

CPU_count=CPU_Count();
printf("Phase 2: CPU count=%lu\n", CPU_count);

Proc->CPU_count=CPU_Count();
printf("Phase 3: CPU count=%lu\n", Proc->CPU_count);

free(Proc);
return(0);
}
else
return(-1);
}

最佳答案

正如 Carl Norum 所提到的,因为您的 asm 语句没有完全描述它对机器状态的影响,可能发生的情况是您破坏了 GCC 用来存储某些值的寄存器。比如 Proc 指针。

解决方案是定义汇编指令的所有输入和输出,以及它破坏的任何其他内容。在这种情况下,尽可能少地在内联汇编中做事,并将其他一切留给编译器也是一个好主意。在您的示例中,只有 cpuid 指令需要在内联汇编中。所以试试这个:

void
cpuid(unsigned value, unsigned leaf,
unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) {
asm volatile("cpuid"
: "=a" (*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
: "a" (value), "c" (leaf));
}

unsigned long int CPU_Count(void)
{
unsigned eax, ebx, ecx, edx;
cpuid(4, 0, &eax, &ebx, &ecx, &edx);
return ((eax >> 26) & 0x3F) + 1;
}

请注意,您确定 CPU 内核数量的方法无法可靠地工作。在我的 4 核 CPU 上,你的程序说我有 8 个核。这是因为您提取的字段给出了最大的 APIC id,而不是实际的核心数。有一个 thread on Intel's web forum解决了这个问题。

关于C 和内联汇编错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31222530/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com