2012年7月5日星期四

cpu_microcode.asm

.686
.model flat, stdcall
option casemap:none

include ntstatus.inc
include ntddk.inc
include ntoskrnl.inc 
includelib ntoskrnl.lib 

.code

szno db "CPU微码没有加载",0
szformat db "加载微码版本为%0d",0

DriverEntry proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING
local state:dword
  
  ;int 3
  
  pushad
  pushfd
  mov ECX, 008bh
  xor EAX, EAX
  xor EDX, EDX
  WRMSR ;//向MSR 8BH写0, 清除MSR中的信息
  
  mov EAX, 0001
  CPUID ;//读CPUID, 让CPU查看微码版本, 并把微码版本送到MSR 8B中
  
  mov ECX, 008bh
  RDMSR ;//读出当前CPU微码版本
  mov state,edx
  popfd
  popad
  
  .if state == 0
    invoke DbgPrint,addr szno
  .else
    invoke DbgPrint,addr szformat,state
  .endif
  
  mov eax, 0
  ret
DriverEntry endp

end DriverEntry
;made at 2011.08.18
;本文改编自网上的相关代码。


檢查 CPU 能否執行 CPUID?
//http://home.educities.edu.tw/wanker742126/

並不是所有的 CPU 都能執行 CPUID 指令,例如 8086/88、80286、80386,當然啦,現在大概也找不到這些 CPU 了,不過還是把檢查的方法說一說。根據英特爾文獻,Intel? Processor Identification and the CPUID Instruction,的記載,如果 CPU 延伸旗標 ( EFLAG ) 的第 21 位元 ( 稱為 ID ) 可以由軟體寫入的話,那麼你的 CPU 可以執行 CPUID。底下是一段檢查的程式碼:

;如果程式可以改變 EFLAGE 的第 21 位元,那麼 CPUID 有效,否則無效
        pushfd                  ;使延伸旗標推入堆疊
        pop     eax             ;把堆疊中的延伸旗標彈出至 EAX
        mov     ecx,eax         ;保存舊的延伸旗標
        xor     eax,200000h     ;改變強制延伸旗標第 21 位元
        push    eax             ;把改變後新的延伸旗標推入堆疊
        popfd                   ;存入延伸旗標
        pushfd                  ;再取出延伸旗標
        pop     eax
        xor     eax,ecx         ;如果延伸旗標的第21位元為1,那麼
        jz      no_cpuid        ;CPUID存在,否則不存在
        ……可以執行 CPUID 指令……
no_cpuid:
        ……不能執行 CPUID 指令……

没有评论:

发表评论