zoukankan      html  css  js  c++  java
  • (汇编源代码 )侦测CPU型号

    _PROCESSOR DETECTION SCHEMES_
    by Richard C. Leinecker
      [LISTING ONE]
      ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;; Detect the Processor Type -- by Richard C. Leinecker         ;;
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
      _PTEXT   SEGMENT PARA PUBLIC 'CODE'
        ASSUME CS:_PTEXT, DS:_PTEXT
      public _Processor
    ; This routine returns the processor type as an integer value.
    ; C Prototype
    ; int Processor( void );
    ; Returns: 0 == 8088, 1 == 8086, 2 == 80286, 3 == 80386, 4 == 80486
    ; Code assumes es, ax, bx, cx, and dx can be altered. If their contents
    ; must be preserved, then you'll have to push and pop them.
    _Processor proc  far
      push  bp     ; Preserve bp
        mov bp,sp      ; bp = sp
      push  ds     ; Preserve ds
        push  di     ; and di
      mov ax,cs      ; Point ds
        mov ds,ax      ; to _PTEXT
      call  IsItAn8088   ; Returns 0 or 2
      cmp al,2      ; 2 = 286 or better
        jge AtLeast286   ; Go to 286 and above code
      call  IsItAn8086   ; Returns 0 or 1
      jmp short ExitProcessor ; Jump to exit code
    AtLeast286:
        call  IsItA286    ; See if it's a 286
      cmp al,3      ; 4 and above for 386 and up
        jl short ExitProcessor ; Jump to exit code
    AtLeast386:
        call  IsItA386    ; See if it's a 386
    ExitProcessor:
        pop di     ; Restore di,
        pop ds     ; ds,
        pop bp     ; and bp
      ret       ; Return to caller
    _Processor endp
      ; Is It an 8088?
    ; Returns ax==0 for 8088/8086, ax==2 for 80286 and above
    IsItAn8088 proc
        pushf        ; Preserve the flags
      pushf        ; Push the flags so
        pop bx     ; we can pop them into bx
      and bx,00fffh    ; Mask off bits 12-15
        push  bx     ; and put it back on the stack
      popf        ; Pop value back into the flags
        pushf        ; Push it back. 8088/8086 will
                            ; have bits 12-15 set
        pop bx     ; Get value into bx
        and bx,0f000h    ; Mask all but bits 12-15
      sub ax,ax      ; Set ax to 8088 value
        cmp bx,0f000h    ; See if the bits are still set
        je Not286     ; Jump if not
      mov al,2      ; Set for 286 and above
    Not286:
        popf        ; Restore the flags
      ret       ; Return to caller
    IsItAn8088 endp
      ; Is It an 8086?
    ; Returns ax==0 for 8088, ax==1 for 8086
    ; Code takes advantage of the 8088's 4-byte prefetch queues and 8086's
    ; 6-byte prefetch queues. By self-modifying the code at a location exactly 5
    ; bytes away from IP, and determining if the modification took effect,
    ; you can differentiate between 8088s and 8086s.
    IsItAn8086 proc
      mov ax,cs     ; es == code segment
        mov es,ax
      std      ; Cause stosb to count backwards
      mov dx,1      ; dx is flag and we'll start at 1
        mov di,OFFSET EndLabel ; di==offset of code tail to modify
        mov al,090h    ; al==nop instruction opcode
        mov cx,3      ; Set for 3 repetitions
        REP stosb     ; Store the bytes
      cld      ; Clear the direction flag
        nop      ; Three nops in a row
        nop      ; provide dummy instructions
        nop
        dec dx     ; Decrement flag (only with 8088)
        nop      ; dummy instruction--6 bytes
    EndLabel:
        nop
      mov ax,dx     ; Store the flag in ax
      ret      ; Back to caller
    IsItAn8086 endp
      ; Is It an 80286?
    ; Determines whether processor is a 286 or higher. Going into subroutine ax = 2
    ; If the processor is a 386 or higher, ax will be 3 before returning. The
    ; method is to set ax to 7000h which represent the 386/486 NT and IOPL bits
    ; This value is pushed onto the stack and popped into the flags (with popf).
    ; The flags are then pushed back onto the stack (with pushf). Only a 386 or 486
    ; will keep the 7000h bits set. If it's a 286, those bits aren't defined and
    ; when the flags are pushed onto stack these bits will be 0. Now, when ax is
    ; popped these bits can be checked. If they're set, we have a 386 or 486.
    IsItA286  proc
        pushf        ; Preserve the flags
        mov ax,7000h    ; Set the NT and IOPL flag
                ; bits only available for
                ; 386 processors and above
        push  ax     ; push ax so we can pop 7000h
                ; into the flag register
        popf        ; pop 7000h off of the stack
        pushf        ; push the flags back on
        pop ax     ; get the pushed flags
                ; into ax
        and ah,70h     ; see if the NT and IOPL
                ; flags are still set
        mov ax,2      ; set ax to the 286 value
        jz YesItIsA286   ; If NT and IOPL not set
                ; it's a 286
        inc ax     ; ax now is 4 to indicate
                ; 386 or higher
    YesItIsA286:
        popf        ; Restore the flags
      ret       ; Return to caller
    IsItA286  endp
      ; Is It an 80386 or 80486?
    ; Determines whether processor is a 386 or higher. Going into subroutine ax=3
    ; If the processor is a 486, ax will be 4 before leaving. The method is to set
    ; the AC bit of the flags via EAX and the stack. If it stays set, it's a 486.
    IsItA386  proc
        mov di,ax      ; Store the processor value
        mov bx,sp      ; Save sp
        and sp,0fffch    ; Prevent alignment fault
    .386
        pushfd       ; Preserve the flags
      pushfd       ; Push so we can get flags
        pop eax     ; Get flags into eax
        or eax,40000h   ; Set the AC bit
        push  eax     ; Push back on the stack
        popfd        ; Get the value into flags
        pushfd       ; Put the value back on stack
        pop eax     ; Get value into eax
        test  eax,40000h   ; See if the bit is set
        jz YesItIsA386   ; If not we have a 386
      add di,2      ; Increment to indicate 486
    YesItIsA386:
        popfd        ; Restore the flags
    .8086
        mov sp,bx      ; Restore sp
        mov ax,di      ; Put processor value into ax
      ret       ; Back to caller
    IsItA386  endp
      _PTEXT   ENDS
        END
    [LISTING TWO]
      .586
    ; Pentium detect routine. Call only after verifying processor is an i486 or
    ; later. Returns 4 if on i486, 5 if Pentium, 6 or greater for future
    ; Intel processors.
    EF_IDequ200000h ; ID bit in EFLAGS register
    Pentium proc near
      ; Check for Pentium or later by attempting to toggle the ID bit in EFLAGS reg;
    ; if we can't, it's an i486.
    pushfd ; get current flags
    popeax ;
    movebx,eax ;
    xoreax,EF_ID; attempt to toggle ID bit
    pusheax ;
    popfd  ;
    pushfd ; get new EFLAGS
    popeax ;
    pushebx ; restore original flags
    popfd  ;
    andeax,EF_ID; if we couldn't toggle ID, it's an i486
    andebx,EF_ID ;
    cmpeax,ebx ;
    jeshort Is486 ;
      ; It's a Pentium or later. Use CPUID to get processor family.
    moveax,1 ; get processor info form of CPUID
    cpuid  ;
    shrax,8 ; get Family field; 5 means Pentium.
    andax,0Fh ;
    ret
    Is486:
    movax,4 ; return 4 for i486
    ret
    pentium endp
    [LISTING THREE]
      #pragma inline
    main()
    {
      long  start1;
      long end1;
      long  start2;
      long end2;
      start1 = clock();
    asm   P386
    asm   mov eax,10000000
    asm   lea ebx,loop1
    asm   loop1: 
    asm   dec eax
    asm   jz loop1e
    asm   jmp ebx
    loop1e:
      start2 = end1 = clock();
    asm   mov eax,10000000
    asm   lea ebx,loop2
    asm   nop
    asm   loop2:
    asm   dec eax
    asm   jz loop2e
    asm   jmp ebx
    loop2e:
      end2 = clock();
       printf("misaligned loop time = %d, aligned loop time =%d
    ",
      (int)(end1-start1), (int)(end2-start2));
      return;
    }
  • 相关阅读:
    mysql工具导出数据库表数据
    c#接收http的post请求的多个文件流
    java上传文件和参数到服务器
    windows server 2008 w3svc服务无法启动
    java调用c#webapi的接口实现文件上传
    postman上线文件上传,并用c#服务端接收
    sql语句修改数据库字段的长度
    VB2015运行项目时出现的错误
    JavaWeb实现分页功能
    会话跟踪技术
  • 原文地址:https://www.cnblogs.com/MaxWoods/p/992902.html
Copyright © 2011-2022 走看看