【问题标题】:x86 assembler cpuid output function parse result of registersx86 汇编器 cpuid 输出函数解析寄存器结果
【发布时间】:2012-12-29 13:25:35
【问题描述】:

我用cpuid 做了一个fasm 程序,输出是:

EAX -> 0x00000662
EBX -> 0x00000000
ECX -> 0x00000000
EDX -> 0x0383FBFF

我使用来自/lib/ld-linux.so.2fprint 来显示这个输出。

所以我需要从EAX 中读取所有标志,... regs 具有某些功能以查看所有规范。

这意味着从寄存器中读取位或输出cpuid 的一个结构。

你能给我一个解决方案吗?

【问题讨论】:

  • 是的,只是从寄存器移动到变量。 gcc.gnu.org/onlinedocs/gcc/…(我假设您使用的是 gcc)
  • 不,我使用 fasm 汇编代码。我使用 use32 制作了一个 ELF 格式可执行文件我使用“_start: mov eax,0x01 cpuid...我使用 fprint 只是为了显示 regs。我需要一个 fasm 解决方案来解析输出。也许对你来说很奇怪,但是我需要学习汇编。
  • 你试过什么?这应该分解为子问题,例如stackoverflow.com/questions/2114163/…

标签: assembly x86 fasm cpuid


【解决方案1】:

来自我很老的kernel project,并使用 GCC 汇编内联:

#define CPUID(VALUE, EAX, EBX, ECX, EDX)                            \
  __asm__ __volatile__ ("   cpuid                   \n\t"           \
                    "       movl    %%eax, %0       \n\t"           \
                    "       movl    %%ebx, %1       \n\t"           \
                    "       movl    %%ecx, %2       \n\t"           \
                    "       movl    %%edx, %3"                      \
                    : "=m" (*EAX), "=m" (*EBX), "=m" (*ECX), "=m" (*EDX) \
                    : "a" (VALUE)                                   \
                    : "%ebx", "%ecx", "%edx"                        \
                    );

顺便说一句,我不确定你在寻找什么......

【讨论】:

    【解决方案2】:

    虽然不是fasm,但请看一下Linux内核如何使用它(GNU asm):

    static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
                                    unsigned int *ecx, unsigned int *edx)
    {
            /* ecx is often an input as well as an output. */
            asm volatile("cpuid"
                : "=a" (*eax),
                  "=b" (*ebx),
                  "=c" (*ecx),
                  "=d" (*edx)
                : "0" (*eax), "2" (*ecx)
                : "memory");
    }
    
    
    /* Some CPUID calls want 'count' to be placed in ecx */
    static inline void cpuid_count(unsigned int op, int count,
                                   unsigned int *eax, unsigned int *ebx,
                                   unsigned int *ecx, unsigned int *edx)
    {
            *eax = op;
            *ecx = count;
            __cpuid(eax, ebx, ecx, edx);
    }
    

    最后将所有寄存器读入一个结构体:

    struct cpuid_regs {
            u32 eax, ebx, ecx, edx;
    };
    
    static void cpuid_smp_cpuid(void *cmd_block)
    {
            struct cpuid_regs *cmd = (struct cpuid_regs *)cmd_block;
    
            cpuid_count(cmd->eax, cmd->ecx,
                        &cmd->eax, &cmd->ebx, &cmd->ecx, &cmd->edx);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多