[资料 from asm.yeah.net] 如何检测CPU的主频

来源(Iczelion 的 Win32asm 教程)

[资料 from asm.yeah.net] 如何检测CPU的主频

作者:罗云彬·发布日期:2000-7-21·阅读次数:5016

Win32汇编编程

在这里下载本文的源代码

概述:

说到检测CPU的速度,一般是测试在单位时间内运算的指令条数,但用这种方法有太大的局限性,由于受到很多因素的影响,准确度比较低,特别是在Windows环境下,你不知道在你的程序外别的程序占用了多少的时间片。其实,在586及以上档次处理器中,已经有了一条专用的指令来测试主频,那就是 RDTSC指令,意思是读取时间标记计数器(Read Time-Stamp Counter),Time-stamp counter 是处理器内部的一个64位的MSR (model specific register),它每个时钟增加一个记数。在处理器复位的时候,初始值为0,RDTSC 指令把 TSC的值低32位装入EAX中,高32位装入EDX中。如果CPU的主频是200MHz,那么在一秒钟内,TSC的值增加 200,000,000 次。所以在计算的时候,把两次的TSC差值除以两次的时间差值就是CPU的主频。

程序的结构如下: 初始化的时候设置一个定时器,定时时间为1秒,然后在定时器消息中利用 RDTSC 取得 TSC计数,再和上次保留的值相减,然后除以时间差即可。

源程序:

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;    Programmed by 罗云彬, bigluo@telekbird.com.cn
;    Website: http://asm.yeah.net
;    LuoYunBin's Win32 ASM page (罗云彬的编程乐园)
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;    版本信息
;    CPU 频率 - 利用586指令 rdtsc 计算CPU的频率
;       V1.0 ------    2000年6月21日
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

        .586
        .model  flat, stdcall
        option  casemap :none   ; case sensitive

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;    Include 数据
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

include     windows.inc
include     user32.inc
include     kernel32.inc
include     comctl32.inc
include     comdlg32.inc

includelib  user32.lib
includelib  kernel32.lib
includelib  comctl32.lib
includelib  comdlg32.lib

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;    Equ 数据
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

DLG_MAIN    equ     1000
ID_SPEED    equ     1001

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;    数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

        .data?

dwTickCount dd      ?
dwTSC       dd      ?,?
hInstance   dd      ?
szBuffer    db      256 dup    (?)

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;    子程序声明
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgMain    PROTO    :DWORD,:DWORD,:DWORD,:DWORD

        .data

szSpeed db      "你的CPU主频为 %d MHz",0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;    代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

        .code

include Win.asm

;********************************************************************
_ProcDlgMain    proc    uses ebx edi esi, \
        hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD
        local   @stPoint:POINT
        local   @hWindow

        mov     eax,wMsg
        .if         eax == WM_CLOSE
            invoke  EndDialog,hWnd,NULL
            invoke  KillTimer,hWnd,1
        .elseif     eax == WM_INITDIALOG
            invoke  _CenterWindow,hWnd
            invoke  GetTickCount    ;TSC 初始值
            mov     dwTickCount,eax

            rdtsc
            mov     dwTSC,eax
            mov     dwTSC+4,edx
            invoke  SetTimer,hWnd,1,1000,NULL
        .elseif     eax == WM_TIMER
            invoke  GetTickCount
            push    eax
            sub     eax,dwTickCount
            pop     dwTickCount
            push    eax

            rdtsc
            push    edx
            push    eax
            sub     eax,dwTSC
            sbb     edx,dwTSC+4
            pop     dwTSC
            pop     dwTSC+4

            mov     ecx,1000000
            div     ecx             ;除以1Mhz=1000000hz
            .if     edx >= 500000h  ;四舍五入
                inc     eax
            .endif
            mov     ecx,1000
            mul     ecx             ;1秒=1000毫秒
            pop     ecx             ;pop出经过的毫秒数
            div     ecx

            invoke  wsprintf,offset szBuffer,offset szSpeed,eax
            invoke  SendDlgItemMessage,hWnd,ID_SPEED,\
                        WM_SETTEXT,0,offset szBuffer
        .else
;********************************************************************
;    注意:对话框的消息处理后,要返回 TRUE,对没有处理的消息
;    要返回 FALSE
;********************************************************************
            mov    eax,FALSE
            ret
        .endif        
        mov     eax,TRUE
        ret
        
_ProcDlgMain    endp
;********************************************************************
start:
        invoke  GetModuleHandle,NULL
        mov     hInstance,eax
        invoke  DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _ProcDlgMain,0
        invoke  ExitProcess,NULL

        end     start


Link: http://www.asm32.net/article_details.aspx?id=2617


浏览次数 280 发布时间 2007/2/22 22:56:45 从属分类 Win32汇编编程 【评论】【 】【打印】【关闭
 
| www.asm32.net | 2006版 | 资料中心 | linux | asm/asm32 | C/C++ | VC++ | java | Python | 书签 | ASP.Net书签 | 京ICP备09029108号-1