【问题标题】:Add variable in assembly instruction (asm inline C example)在汇编指令中添加变量(asm 内联 C 示例)
【发布时间】:2018-09-15 23:47:15
【问题描述】:

我想执行 asm 代码行的循环。 实际上我正在尝试读取我的核心的 CPUID,需要读取 CPUID 的所有参数。 如果我将 0 写入 eax 寄存器,那么我将获得制造商名称,如果我将 1 写入 eax,则将收到下一组 CPUID 信息。等等... 现在我想执行多达 15 组 asm 指令以获得完整的 CPUID 输出。

例如: 无符号整数 cpuid_reg[4];

    __asm__ volatile("mov $1, %eax");
    __asm__ volatile("cpuid" : "=a" (cpuid_reg[0]), "=b" (cpuid_reg[1]), "=c" (cpuid_reg[2]), "=d" (cpuid_reg[3]));
    printf("reg[0] 0x%x , cpuid_reg[1] 0x%x, cpuid_reg[2] 0x%x, cpuid_reg[3] 0x%x\n", cpuid_reg[0], cpuid_reg[1], cpuid_reg[2], cpuid_reg[3]);


    __asm__ volatile("mov $2, %eax");
    __asm__ volatile("cpuid" : "=a" (cpuid_reg[0]), "=b" (cpuid_reg[1]), "=c" (cpuid_reg[2]), "=d" (cpuid_reg[3]));
    printf("cpuid_reg[0] 0x%x , cpuid_reg[1] 0x%x, cpuid_reg[2] 0x%x, cpuid_reg[3] 0x%x\n", cpuid_reg[0], cpuid_reg[1], cpuid_reg[2], cpuid_reg[3]);

我需要一组代码,而不是这两组代码,我可以将 0 到 15 写入“eax”寄存器,以获取完整的 CPUID 数据。 感谢您的帮助。

【问题讨论】:

  • 使用编译器内在而不是内联汇编。
  • 如果您正在使用__asm__ volatile,并且您正在编写线程之间不同步的用户空间代码,那么volatile 几乎总是错误的,并且表明 asm 块操作数不是正确指定。
  • 使用 cpuid.h 中的__get_cpuid 怎么样?
  • 顺便说一下,您需要进行超过 15 次 cpuid 调用才能获得有关最近 CPU 的完整信息。对于eax的某些值,需要在ecx中多次使用cpuid不同的值。

标签: c assembly inline-assembly


【解决方案1】:

您可以阅读 thisthis 之类的内容

static inline void cpuid(int code, uint32_t *a, uint32_t *d) {
  asm volatile("cpuid":"=a"(*a),"=d"(*d):"a"(code):"ecx","ebx");
}

/** issue a complete request, storing general registers output as a string
 */
static inline int cpuid_string(int code, uint32_t where[4]) {
  asm volatile("cpuid":"=a"(*where),"=b"(*(where+1)),
               "=c"(*(where+2)),"=d"(*(where+3)):"a"(code));
  return (int)where[0];
}

【讨论】:

  • 你可以像普通人一样写"=b"(where[1]),而不是*(where+1)。但是,是的,"a"(code) 输入约束是要走的路。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-02
  • 2018-04-17
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
相关资源
最近更新 更多