Sunday 3 March 2013

CPUID x64


;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

.data ;http://www.youtube.com/watch?v=p5X1Sf5ejCc
vendorString db 12 dup(0),0 ;//13 characters long , 0 at the end
str1   db  8 ;// cpuid -    1
str2   db  8 ;//cpuid  -    3
.code
;=========================================================================================
;bool GetCPUISupport()
;This function test if my CPU can call CPUID instruction
;by setting the ID flag (bit 21 ) in the flag register to 1
;and checking if the change stuck . if you can't set this flag
;(if your CPU automatically reset it to 0) the the CPU
;doesn't know the CPUID instruction .This is Extreamely unlikely
GetCPUIDSupport proc
       PUSH rbx         ; save caller's RBX
  PUSHFQ           ;Push the flag regiter
  POP rax           ; pop it into eax
  MOV  rbx ,rax     ;save the value into E0X,We pushed the 64 bit rflags
                    ;it is here that my version is different from that in
    ;the AMD manual since their version is for 32 bit
  XOR rax , 200000h ;set bit 21 ,the ID flag ,to 1
  PUSH rax          ;push this toggled flags register
       POPFQ             ;pop the toggled flags back into the flaags register
                         ;it is at this point that the cpu will either automatically    
                         ;reset the 21st bit to 0 or leave it as 1 depending on
 ;whether or not it know about the CPUID instruction !
       PUSHFQ             ;push the flags again (has the bit changed ?)
       POP  rax           ;push the flag into EAX again
       CMP  rax ,rbx      ;compare the flags to the E0X version we saved earlier
 
  JZ  No_CPUID
  POP rbx          ;restore the caller's RBX
  MOV rax ,1       ;This CPU does understand CPUID !
  RET              ;return TRUE ,EAX = 1

No_CPUID :
   POP rbx         ; restore caller's RBX
MOV rax , 0     ;this CPU does not undertand CPUID
RET             ; Return false ,EAX = 0

GetCPUIDSupport endp
;===========================================================================================
;char* GetVendorString()
;CPUID_0000_0000_EBX:EDX:ECX  is the vendor string  !
GetVendorString proc
push rbx              ; save  RBX , it's not scratch our caller will want it
mov eax , 0           ; Move function number o into EAX
cpuid                 ;call CPUID
lea rax ,VendorString ; load  address  of "vendorString into rax"
   
    ; move the registers into "vendorString in the special order :
    mov dword ptr[rax] ,ebx      ;1st 4 bytes of vendor string are is ebx
mov dword ptr[rax+4] ,edx    ;2nt 4bytes of vendor string are in ebx
    mov dword ptr[rax+8] ,ecx    ;3rd  4bytes of vendor string are in ecx

pop rbx    ; restore the caller's  RBX
ret        ; return with RAX pointing to the answer in vendorString
GetVendorString endp
;=========================================================================================
;int getLargetstStandardFunction()
;CPUID_0000_0000__EAX  is the largest standard function my CPU knows
getLargetstStandardFunction proc
push  rbx     ;save  caller's rbx
mov eax , 1    ;move function o into eax
cpuid          ;call CPUID
pop rbx       ;restore caller's rbx
mov eax , edx
ret           ;return with largest standard function eax
getLargetstStandardFunction endp
;=========================================================================================
;int GetLogicprocessorCount
;CPUID_0000_0001_EBX(bit 23:16) are the number of logical  cores
GetLogicalProcessorCount proc
push rbx       ; save the caller's RBX
mov eax ,1  ;function number is 1
cpuid ; call CPUID
and ebx , 00ff0000h ; mask out all bits other than 16 to 23
mov eax ,ebx  ; mov the bit 16 to 23 into EAX
pop rbx   ;restore the caller's RBX
shr eax ,16 ; restore the caller's RBX
ret  ; shift the utanswer right so we can print it out
GetLogicalProcessorCount endp
;=========================================================================================
;bool DetectFeatureEDX(char BitNumber = cl)
;CPUID_0000_0001_EDX(  bit x ) is set to 1 if future x is enable
;other it's 0 .This function takes a single paramater that is
;the bit number for the function you are interedtedt in testing fot
DetectFeatureEDX proc
  push rbx  ; save the caller's RBX
   mov r8b ,cl ;save the feature they're lookinf fto into r8b
             ;because cpuid will set ECX and we obviousky need to
  ;remenber the bit number the caller is checking
   mov eax ,1 ; function number 1 into eax
  cpuid                 ; call cpuid
  mov eax ,edx         ; move the bit answers from EDX to EAX
  mov cl ,r8b           ; move the bit number they're from RBB back into CL
                       ;because we're going to shift-right to move this bit to the
           ;0the position in EAX , recall that the only way to SHR
           ;a variablr amount is to use CL as the parameter
  shr eax ,cl           ; shift this bit to the oth possition of EAX
  and eax ,1            ; mask out the unwanted bits (all but bbit 0)
  pop rbx                ; restore the caller's RBX
  ret ; return 0 or 1 in AL
 DetectFeatureEDX endp
;=========================================================================================  
;bool DetectFeatureECX(char bitNumber = cl)
;CPUID_0000_0001_ECX( bit x) is set to 1 if feature x is enabled
;otherwise it's 0 .this function takes a single parameter that is
;the bit number for the function you are intered in testing for
DetectFeatureECX proc
     push rbx
mov r8b ,cl
mov eax ,1
cpuid
mov eax ,ecx
mov cl ,r8b
shr eax ,cl
and eax ,1
pop rbx
ret           ; return 0 or 1 in AL
DetectFeatureECX endp
;=========================================================================================
 GetCPUID1edx proc
push  rbx     ;save  caller's rbx
mov eax , 1    ;move function o into eax
xor edx ,edx  ;
cpuid          ;call CPUID
pop rbx       ;restore caller's rbx
mov eax , edx
ret           ;return with largest standard function eax
GetCPUID1edx endp
;//----------------------------------------------------------------
GetCPUID1eax proc
push  rbx     ;save  caller's rbx
mov eax , 1    ;move function o into eax
cpuid          ;call CPUID
pop rbx       ;restore caller's rbx
ret           ;return with largest standard function eax
GetCPUID1eax endp
;//----------------------------------------------------------------
 GetCPUID3edx proc
push  rbx     ;save  caller's rbx
mov eax , 3    ;move function o into eax
xor edx ,edx  ;
cpuid          ;call CPUID
pop rbx       ;restore caller's rbx
mov eax , edx
ret           ;return with largest standard function eax
GetCPUID3edx endp
;//----------------------------------------------------------------
GetCPUID3ecx proc
push  rbx     ;save  caller's rbx
mov eax , 3    ;move function o into eax
xor ecx, ecx ;
cpuid          ;call CPUID
pop rbx       ;restore caller's rbx
mov eax , edx
ret           ;return with largest standard function eax
GetCPUID3ecx endp
end
;--------------------------------------------------------------------------------------------------------





//#include <stdexcept>
#include "x64Processor.h"
#include <string.h>
#include <iostream>
using namespace std;
extern "C"  bool GetCPUIDSupport();
extern "C"  char* GetVendorString();
extern "C"  unsigned long getLargetstStandardFunction();
extern "C"  int  GetLogicalProcessorCount();
extern "C"  bool  DetectFeatureEXC(char);
extern "C"  bool  DetectFeatureEDX(char);
extern "C" unsigned long GetCPUID1edx();
extern "C" unsigned long GetCPUID1eax();
extern "C" unsigned long GetCPUID3edx();
extern "C" unsigned long GetCPUID3ecx();

namespace x64
{

void x64::CPUinfo(char buff[],int size)
{
if(GetCPUIDSupport())
{
cout<<"GetCPUID1edx :"<<GetCPUID1edx()<<endl;
cout<<"GetCPUID1eax :"<<GetCPUID1eax()<<endl;
cout<<"GetCPUID3edx :"<<GetCPUID3edx()<<endl;
cout<<"GetCPUID3ecx :"<<GetCPUID3ecx()<<endl;
}else
{
memset(buff,0,100);
}
}
}

No comments:

Post a Comment