如何检测计算机速度

54lem 2003-12-12 07:19:31
用汇编语言实现检测计算机速度
应该如何做

高手请给个算法或提示
我真的无从下手,哎

编写一个检测计算机速度的程序。
要求:能够准确测定计算机的速度,并且通过该程序,基本识别CPU的工作频率。
如:
C:\>speed
P2 100 speeds is 10000
Your computer is P3 500!
Speed is 40000!!
...全文
117 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
54lem 2003-12-16
  • 打赏
  • 举报
回复
wenhaoy(wenhaoy)
对不起
你所贴的罗云彬的程序给了我很大的启发
我现在才看到

你的问题可以用 CPUID 指令,来实现
你可以去找一下资料
如果不能找到
请留下你的E——MAIL
54lem 2003-12-14
  • 打赏
  • 举报
回复
利用Rdtsc指令计算CPU的时钟频率 By 怜香(于2003-11-15发表)

--------------------------------------------------------------------------------

; 参 精华帖“使用CPU时间戳进行高精度计时(转载) By IPOz(于2002-11-18发表)”

; 利用Rdtsc指令计算CPU的时钟频率
; 文件名:Cpu.Asm
; Dos下 .Com 格式文件

.model tiny
.586
.code
org 100h
start:
lea dx,Message ;显示信息
mov ah,9
int 21h

xor ax,ax
mov ds,ax
mov ebx,ds:[46ch] ;取时间,每55ms该值自动增1
rdtsc
mov esi,eax
mov edi,edx
mov ecx,ebx
bb:
cmp ecx,ds:[46ch]
jz bb

mov ecx,ds:[46ch]
rdtsc

push ecx
sub ecx,ebx
sub eax,esi
sbb edx,edi
push eax
push edx
mov eax,55000
mul ecx
mov ecx,eax
pop edx
pop eax
div ecx
call dispax
pop ecx

mov eax,ecx
sub eax,ebx
cmp ax,500 ;约30秒后自动退出
ja Over
mov ah,1 ;检测是否有按键
int 16h
jz bb
mov ah,0 ;有,则读按键
int 16h
Over:
mov ah,4ch ;程序结束
int 21h

; 显示AL代表的ASCII码字符
dispc proc NEAR
PUSH AX
PUSH DX
MOV AH,2
MOV DL,AL
INT 21H
POP DX
POP AX
RET
dispc endp


;以十进制的形式显示AX的值,显示所占的位数为CX
;若CX的值小于数据的实际宽度则按实际宽度输出
dispax proc near
push ax
push bx
push cx
push dx
push bp
mov cx,5 ;输出数据宽度5位
mov bx,0 ;记录数据实际宽度
mov bp,10 ;十进制
disp1:
xor dx,dx
div bp
inc bx ;显示数据的位数增1
push dx ;保存余数
cmp ax,0 ;商为0 ?
jnz disp1 ;没,继续!
sub cx,bx ;要求宽度和实际宽度比较
jle disp3
mov al,' ' ;宽度不够,前面补空格
disp2:
call dispc
loop disp2
disp3:
mov cx,bx ;数据的实际位数送CX
disp4:
pop ax ;依次从堆栈中取数并显示
and al,0fh
add al,'0'
call dispc
loop disp4
call SetPos
pop bp ;恢复寄存器的原值
pop dx
pop cx
pop bx
pop ax
ret
dispax endp

SetPos proc near ;调整光标位置
push ax
push dx
push ds
push cs
pop ds
lea dx,Back
mov ah,9
int 21h
pop ds
pop dx
pop ax
ret
SetPos endp

Even

Message db 13,10,'Press any key to STOP !',13,10,13,10
db 'Cpu Speed: MHz',8,8,8,8
Back db 8,8,8,8,8,'$'

end start

;--------------------------------------------------------------
编译链接

D:\Masm615>ml Cpu.asm
Microsoft (R) Macro Assembler Version 6.15.8803
Patched for you by promethee [ECL] in the year 2001 - enjoy
Copyright (C) Microsoft Corp 1981-2000. All rights reserved.

Assembling: Cpu.asm

Microsoft (R) Segmented Executable Linker Version 5.60.339 Dec 5 1994
Copyright (C) Microsoft Corp 1984-1993. All rights reserved.

Object Modules [.obj]: Cpu.obj /t
Run File [Cpu.com]: "Cpu.com"
List File [nul.map]: NUL
Libraries [.lib]:
Definitions File [nul.def]:

D:\Masm615>Cpu

Press any key to STOP !

Cpu Speed: 1000 MHz
D:\Masm615>_

54lem 2003-12-14
  • 打赏
  • 举报
回复
另外
就是
主要问题在于检测 CPU 的速度
而上面的那个程序不能实现这一点
有没有检测 CPU 速度的算法或是源代码
xygod 2003-12-14
  • 打赏
  • 举报
回复
去看看奔腾指令就明白了,呵呵!
kugou123 2003-12-14
  • 打赏
  • 举报
回复
罗云彬的例程需要WIN32环境的编译器如MASM32 V8或者V7
54lem 2003-12-14
  • 打赏
  • 举报
回复
不用windows 的API 函数应该怎么做
罗云彬的用了WINDOWS 的 API 呀

zongta() 兄
我用 MASM5。0 来编译程序没有通过
那个程序是不是应该用TASM

最近很忙
作业好多,所以来得迟了点
SORRY呀
wenhaoy 2003-12-13
  • 打赏
  • 举报
回复
我还有个问题,怎么册cpu的原始频率?如果cpu抄频了,怎么测出抄频前的频率?
wenhaoy 2003-12-13
  • 打赏
  • 举报
回复
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 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


可以直接测主频,罗云彬写的
hswxf 2003-12-13
  • 打赏
  • 举报
回复
可以检测的,查一下以前有许多贴子讨论过这个问题,
zongta 2003-12-12
  • 打赏
  • 举报
回复
check_vendor:
.586
mov id_flag, 1 ; set flag for indicating use of
;CPUID inst
mov eax, 0 ;set up for CPUID instruction
cpuid
mov dword ptr vendor_id, ebx; Test for "GenuineIntel" vendor id.
mov dword ptr vendor_id[+4], edx
mov dword ptr vendor_id[+8], ecx
mov si, offset vendor_id
mov di, offset intel_id
mov cx, length intel_id
compare:
repe cmpsb
cmp cx, 0 ; must be a GenuineIntel if ecx =0
jne cpuid_data

intel_processor:
mov intel_proc, 1
mov [intel-1], ' ' ; add a space so the Genuine Intel
; message prints out.

cpuid_data:
mov eax, 1
cpuid
mov saved_cpuid,eax ;save for future use
and eax, 0F00H ; mask everything but family
shr eax, 8
mov cpu_type, al ; set cpu_type with family

mov eax,saved_cpuid ;restore data
mov stepping, al
and stepping, 0FH ; isolate stepping info

mov eax, saved_cpuid
mov themodel, al
and themodel, 0F0H ; isolate model info
shr themodel, 4

end_get_cpuid:
.8086
ret
get_cpuid endp

;
; This procedure prints the appropriate cpuid string
; If the CPUID instruction was supported, it prints out
; the cpuid info.

print proc
push ax
push bx
push cx
push dx
cmp id_flag, 1 ; if set to 1, cpu supported CPUID
; instruction
; print detailed CPUID information
je print_cpuid_data

mov dx, offset id_msg
mov ah, 9h
int 21h ; print initial message

print_86:
cmp cpu_type, 0
jne print_286
mov dx, offset c8086
mov ah, 9h
int 21h
jmp end_print

print_286:
cmp cpu_type, 2
jne print_386
mov dx, offset c286
mov ah, 9h
int 21h
jmp end_print


print_386:
cmp cpu_type, 3
jne print_486
mov dx, offset c386
mov ah, 9h
int 21h
jmp end_print


print_486:
mov dx, offset c486
mov ah, 9h
int 21h
jmp end_print

print_cpuid_data:

cmp cpu_type, 5
jne print_cpuid_cont

mov dx, offset Pentium
mov ah, 9
int 21h

print_cpuid_cont:
mov dx, offset familymsg ;print family msg
mov ah, 9h
int 21h
mov al, cpu_type
mov byte ptr dataCR, al
add byte ptr dataCR, 30H ; convert to ASCII
mov dx, offset dataCR ; print family info
mov ah, 9h
int 21h

mov dx, offset steppingmsg ; print stepping msg
mov ah, 9h
int 21h
mov al, stepping
mov byte ptr dataCR, al
add byte ptr dataCR, 30H ; convert to ASCII
mov dx, offset dataCR ; print stepping info
mov ah, 9h
int 21h

mov dx, offset modelmsg ; print model msg
mov ah, 9h
int 21h
mov al, themodel
mov byte ptr dataCR, al
add byte ptr dataCR, 30H ; convert to ASCII
mov dx, offset dataCR ; print stepping info
mov ah, 9h
int 21h
end_print:
pop dx
pop cx
pop bx
pop ax
ret
print endp

end start
zongta 2003-12-12
  • 打赏
  • 举报
回复
你的问题是取得CPU ID 问题。我从TASM Debuger 中的例行程序中找到了一个跟你的要求差不多的程序,以下便是:

; cpuid.asm
;
; CPU detector program.
;
; Copyright (c) 1993 by Borland International, Inc.
;
; Build with the provided makefile: make -B


TITLE CPUID
JUMPS
.model small
.stack 100h
.data
saved_cpuid dd ?
vendor_id db 12 dup (?)
cpu_type db ?
themodel db ?
stepping db ?
id_flag db 0
intel_proc db 0
id_msg db "This system has a$"
c8086 db "n 8086/8088 microprocessor$"
c286 db "n Intel 286 microprocessor$"
c386 db "n Intel386 (TM) microprocessor$"
c486 db "n Intel486 (TM) DX microprocessor$"
Pentium db " Pentium(TM) microprocessor", 13, 10, "$"
intel db "This system contains a Genuine Intel Processor", 13, 10, "$"
modelmsg db "Model: $"
steppingmsg db "Stepping: $"
familymsg db "Processor Family: $"
period db ".",13,10,"$"
dataCR db ?,13,10,"$"
intel_id db "GenuineIntel"

.code
.8086 ; This part of the program must run on an 8086
start: mov ax,@data
mov ds, ax ;set segment register
mov es, ax ;set segment register
and sp, not 3 ;align stack to avoid AC fault
call get_cpuid
call print
mov ax,4c00h ; terminate program
int 21h

get_cpuid proc

; 8086 CPU check
; Bits 12-15 are always set on the 8086 processor
;
check_8086:
pushf ;save FLAGS
pop bx ;store FLAGS in BX
mov ax, 0fffh ;clear bits 12-15
and ax, bx ; in FLAGS
push ax ;store new FLAGS calue on stack
popf ;replace current FLAGS value
pushf ;set new flags
pop ax ;store new flags in AX
and ax, 0f000h ;if bits 12-15 are set, then CPU
cmp ax, 0f000h ; is an 8086/8088
mov cpu_type, 0 ; save the CPU type
je end_get_cpuid


;
; Intel 286 CPU check
; Bits 12-15 are always clear on the Intel processor.
;
check_80286:
.286
or bx, 0f000h ;try to set bits 12-15
push bx
popf
pushf
pop ax
and ax, 0f000h ; if bits 12-15 are cleared,
; CPU=Intel 286
mov cpu_type, 2 ; turn on Intel 286 Cpu flag
jz end_get_cpuid ; if CPU is intel 286, check
; for Intel 287 math coprocessor

; Intel386 CPU check
; The AC bit (bit 18), is a new bit introduced in the EFLAGS
; register on the Intel486 DX CPU to generate alignment faults.
; This bit can not be set on the Intel386 CPU.
;
check_intel386:
.386
pushfd
pop eax ;get original EFLAGS
mov ecx,eax ; save original EFLAGS
xor eax,40000h ;flip AC bit in EFLAGS
push eax ; save for EFLAGS
popfd ; copy to EFLAGS
pushfd ; push EFLAGS
pop eax ; get new EFLAGS value
xor eax,ecx ; can't toggle AC bit, CPU=Intel386
mov cpu_type, 3 ; turn on Intel386 CPU flag
je end_get_cpuid ; if CPU is Intel386, now check
; for an Intel 287 or Intel387 MCP

; Intel486 DX CPU, Intel 487 SX MCP, and Intel486 SX CPU checking
;
; Checking for the ability to set/clear the ID flag (bit 21) in EFLAGS
; which diferentiates between Pentium (or greater) and the Intel486.
; If the ID flag is set then the CPUID instruction can be used to
; determine the final version of the chip, else it's a 486
;
;
check_Intel486:
.486
mov cpu_type, 4 ;turn on Intel486 CPU flag
pushfd ;push original EFLAGS
pop eax ; get original EFLAGS in eax
mov ecx,eax ;save original EFLAGS in ecx
or eax,200000h ; flip ID bit in EFLAGS
push eax ;save for EFLAGS
popfd ;copy to EFLAGS
pushfd ;push EFLAGS
pop eax ;get new EFLAGS value
xor eax,ecx
je end_get_cpuid ;if ID bit cannot be changed,
;CPU=Intel486 without CPUID
;instruction functionality

; Otherwise, execute CPUID instruction to determine vendor,
; family, model and stepping.

54lem 2003-12-12
  • 打赏
  • 举报
回复
高手给个算法呀
很急
网上找了半天也没有找到
54lem 2003-12-12
  • 打赏
  • 举报
回复
很难不仅仅只在于程序本身
在于算法也很难找到
qass 2003-12-12
  • 打赏
  • 举报
回复
的确很难,建议找相应的算法来看.
54lem 2003-12-12
  • 打赏
  • 举报
回复
有没有高手帮帮忙呀
好急!
先谢了
54lem 2003-12-12
  • 打赏
  • 举报
回复
不可能吧
这个题目很难
没有人敢回答?

21,459

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧