首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >坏了CPUID品牌线?

坏了CPUID品牌线?
EN

Stack Overflow用户
提问于 2016-04-10 03:13:12
回答 1查看 1.5K关注 0票数 3

我正在使用CPUID指令在操作系统中打印一些有关CPU的信息。

阅读和打印供应商字符串(GenuineIntel)工作良好,但阅读品牌字符串给我一点奇怪的字符串。

代码语言:javascript
复制
ok cpu-info <= Run command
CPU Vendor name: GenuineIntel <= Vendor string is good
CPU Brand: D:  l(R)  Core(TMD:   CPU       MD:  <= What..?
ok

供应商字符串应该是:

代码语言:javascript
复制
Intel(R) Core(TM) i5 CPU       M 540

但我得到的是:

代码语言:javascript
复制
 D:  l(R)  Core(TMD:   CPU       MD:

C++代码:

代码语言:javascript
复制
            char vendorString[13] = { 0, };
            Dword eax, ebx, ecx, edx;
            ACpuid(0, &eax, &ebx, &ecx, &edx);
            *((Dword*)vendorString) = ebx;
            *((Dword*)vendorString + 1) = edx;
            *((Dword*)vendorString + 2) = ecx;
            Console::Output.Write(L"CPU vendor name: ");
            for (int i = 0; i < 13; i++) {
                Console::Output.Write((wchar_t)(vendorString[i]));
            }
            Console::Output.WriteLine();

            char brandString[48] = { 0, };
            ACpuid(0x80000002, &eax, &ebx, &ecx, &edx);
            *((Dword*)brandString) = eax;
            *((Dword*)brandString + 1) = ebx;
            *((Dword*)brandString + 2) = ecx;
            *((Dword*)brandString + 3) = edx;
            ACpuid(0x80000003, &eax, &ebx, &ecx, &edx);
            *((Dword*)brandString + 4) = eax;
            *((Dword*)brandString + 5) = ebx;
            *((Dword*)brandString + 6) = ecx;
            *((Dword*)brandString + 7) = edx;
            ACpuid(0x80000004, &eax, &ebx, &ecx, &edx);
            *((Dword*)brandString + 8) = eax;
            *((Dword*)brandString + 9) = ebx;
            *((Dword*)brandString + 10) = ecx;
            *((Dword*)brandString + 11) = edx;
            Console::Output.Write(L"CPU brand: ");
            for (int i = 0; i < 48; i++) {
                Console::Output.Write((wchar_t) brandString[i]);
            }
            Console::Output.WriteLine();

注意:

  1. 这个程序是UEFI应用程序。权限没有问题。
  2. console是EFI控制台的包装类。不是C#的东西。
  3. Dword =无符号32位整数

装配代码(MASM):

代码语言:javascript
复制
;Cpuid command
;ACpuid(Type, pEax, pEbx, pEcx, pEdx)
ACpuid Proc
    ;Type => Rcx
    ;pEax => Rdx
    ;pEbx => R8
    ;pEcx => R9
    ;pEdx => [ rbp + 48 ] ?
    push rbp
    mov rbp, rsp
    push rax
    push rsi

    mov rax, rcx
    cpuid
    mov [ rdx ], eax
    mov [ r8 ], ebx
    mov [ r9 ], ecx
    mov rsi, [ rbp + 48 ]
    mov [ rsi ], rdx

    pop rsi
    pop rax
    pop rbp
    ret
ACpuid Endp
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-10 04:39:19

我同意Ridge的观点,您应该使用编译器内部的丘比特。至于为什么您的代码可能无法按原样工作,有一些bug会导致问题。

https://en.wikipedia.org/wiki/CPUID破坏了RAX、RBX、RCX和RDX的内容,但是您可以在代码中这样做:

代码语言:javascript
复制
cpuid
mov [ rdx ], eax

RDX在执行mov [ rdx ], eax时已被销毁,使RDX中的指针无效。在使用CPUID指令之前,您需要将RDX移动到另一个寄存器。

根据Windows 64位呼叫约定,这些是需要由调用方保存的易失性寄存器

寄存器RAX、RCX、RDX、R8、R9、R10、R11被认为是易失性的,必须在函数调用时考虑销毁(除非通过分析(如整个程序优化)可以证明另有安全性)。

这些是需要由callee保存的非易失性的。

寄存器RBX、RBP、RDI、RSI、RSP、R12、R13、R14和R15被认为是非易失性的,必须由使用它们的函数保存和恢复。

我们可以使用R10 (一个易失性寄存器)暂时存储RDX。与其在代码中使用RSI,我们还可以重用R10来更新pEdx上的值。如果我们不使用它,我们就不需要保存RSI。CPUID确实会破坏RBX,而RBX是非易失性的,所以我们需要保存它。拉克斯是不稳定的,所以我们不需要保存它。

在您的代码中有以下一行:

代码语言:javascript
复制
mov [ rsi ], rdx

RSI是调用方为在EDX中存储值而提供的内存地址(pEdx)。您所拥有的代码将将8字节寄存器RDX的内容移动到一个需要4字节DWORD的内存位置。这可能会破坏调用方中的数据。这真的应该是:

代码语言:javascript
复制
mov [ rsi ], edx

考虑到以上所有内容,我们可以这样对ACpuid例程进行编码:

代码语言:javascript
复制
option casemap:none
.code

;Cpuid command
;ACpuid(Type, pEax, pEbx, pEcx, pEdx)
ACpuid Proc
    ;Type => Rcx
    ;pEax => Rdx
    ;pEbx => R8
    ;pEcx => R9
    ;pEdx => [ rbp + 48 ] ?
    push rbp
    mov rbp, rsp
    push rbx         ; Preserve RBX (destroyed by CPUID)

    mov r10, rdx     ; Save RDX before CPUID
    mov rax, rcx
    cpuid
    mov [ r10 ], eax
    mov [ r8 ], ebx
    mov [ r9 ], ecx
    mov r10, [ rbp + 48 ]
    mov [ r10 ], edx ; Last parameter is pointer to 32-bit DWORD, 
                     ;  Move EDX to the memory location, not RDX

    pop rbx
    pop rbp
    ret
ACpuid Endp

end
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36525340

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档