ورود

View Full Version : تعیین سرعت cpu در سیستم مبتنی بر 86



amin.gon
جمعه 19 دی 1393, 16:14 عصر
سلام بر مهندسین عزیز
من میخوام برنامه ی بنویسم که برای یک سیستم مبتنی بر86 سرعت cpu رو تعیین کنه راهنمایی بفرماید.ممنونم.

masoud.8086
جمعه 19 دی 1393, 17:27 عصر
سلام
در رابطه با سوال شما باید چندین نکتو عرض کنم اول اینکه این کار به این راحتیا نیس..
اول باید ببینیم سازنده قطعه امکاناتی برای این کاری که شما میخواید انجام بدید تدارک دیده یا یا نه!!شاید سازنده وقتی قطعه رو ساخته این امکان رو نذاشته که برنامه نویس بتونه روی سی پی یو کنترل داشته باشه نکته بعدی اینه که وقتی سازنده قطعه رو میسازه با استفاده از کدهای که خودش تعیین کرده با آن در ارتباطه و این کدها انحصاری هست ..به نظر من کتاب معماری موریس مانو رو مطالعه کن.

Delphi Coder
شنبه 20 دی 1393, 13:05 عصر
این سوال خیلی کلی تر از اونی هست که بشه به سادگی پاسخ داد. توی گوگل هم اگر سرچ کنید بحثهای زیادی در مورد این موضوع انجام شده و کدهایی هم برای این منظور هست اما باید دید ما در مورد چه محیطی بحث میکنیم. این کار در ویندوز میتونه به سادگی خواندن یک عدد از رچیستری باشه HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\Cen tralProcessor\0
یا محاسبه تقریبی با RDTSC. برای توضیحات بیشتر اینجــــــــــــآ (http://www.codeproject.com/Articles/7340/Get-the-Processor-Speed-in-two-simple-ways) رو ببینید.

اگر در محیط DOS در مورد این موضوع صحبت کنیم مشکل به وجود آوردن تاخیر 1 ثانیه ای برای محاسبه سرعت CPU هم مطرح هست که باید از طریق چیپ 8253 (Programmable Interval Timers) پیاده سازی بشه.

از طرفی بحث پشتیبانی از خود دستور RDTSC هم مطرح هست. این دستور در مدلهای قدیمی پردازنده های خانواده 8086 وجود نداره و فکر میکنم از مدلهای اولیه پنتیوم به بعد پشتیبانی بشه و البته سیستم عامل قابلیت فعال یا غیر فعال کردن این دستور رو داره.

راه حل دیگر میتونه استفاده از دستور CPUID باشه که اونهم در مدلهای قدیمی 8086 پشتیبانی نمیشه اما این قابلیت رو داره تا با خواندن اطلاعات CPU و داشتن لیستی از اطلاعات همراه با سرعت Frequency پردازنده ها اطلاعات رو با اطلاعات خوانده شده توسط دستور فوق مقایسه کرد و به سرعت CPU رسید.
در کامپیوترهای قدیمی تر هم میشه از زمان اجرای تعداد مشخصی از دستورات به فرکانس CPU رسید.

Delphi Coder
شنبه 20 دی 1393, 13:14 عصر
کــــــــــــــــــــــــ ــــد برای تشخیص CPU های قدیمی:
کپی شده از http://www.rcollins.org/ftp/source/cpuid/cpuid.asm

; To assemble the code using MASM 5.10:
; MASM cputype;
; LINK cputype;
; EXE2COM cputype;
; Version: 1.00b

; Author: Ben Lunt (Forever Young Software)

; Date: 20 Nov 1997

; The following code won't assemble with NBASM yet, since
; I have not added all the FPU instructions. I hope to get to them soon.
; Until then, you will have to use a different assembler. Sorry.
;

CodeSeg segment
assume cs:CodeSeg, ds:CodeSeg, es:CodeSeg
.186
org 100h
start: mov ax,cs ; free unused part of Mem Block
mov es,ax ; for .COM file format
mov bx,4096 ;
mov ah,4Ah ;
int 21h ;

mov cx,0121h ; If CH can be shifted by 21h,
shl ch,cl ; then it's an 8086, because
jz short p1_8086 ; a 186+ limits shift counts.
push sp ; If SP is pushed as its
pop ax ; original value, then
cmp ax,sp ; it's a 286+.
jne short p1_186
mov ax,7000h ; if bits 12,13,14 are still set
push ax ; after pushing/poping to/from
popf ; the flags register then we have
pushf ; a 386+
pop ax
and ax,7000h
cmp ax,7000h
jne short p1_286 ; it's a 386+
.386
push bp ; Align stack to dword
mov bp,sp
and sp,0FFFCh
pushfd ; Save eflags
cli ; No interrupts
pushfd ; EAX = eflags
pop eax
mov ebx,eax ; EBX = eflags
xor eax,40000h ; Toggle AC bit
push eax ; Eflags = EAX
popfd
pushfd ; EAX = eflags
pop eax
popfd ; Restore eflags
mov sp,bp ; Restore stack
pop bp
cmp eax,ebx ; If the bit was not
je short p1_386 ; reset, it's a 486+
pushfd ; Save eflags
cli ; No interrupts
pushfd ; EAX = eflags
pop eax
xor eax,200000h ; Toggle ID bit
push eax ; Eflags = EAX
popfd
pushfd ; EBX = eflags
pop ebx
popfd ; Restore eflags
cmp eax,ebx ; If the bit was not
jne short p1_486 ; reset, it's a 586+
mov dx,offset CPUType5 ; 586+
jmp short cpudone
p1_486: mov dx,offset CPUType4 ; 486
jmp short cpudone
p1_386: mov dx,offset CPUType3 ; 386
jmp short cpudone
p1_286: mov dx,offset CPUType2 ; 286
jmp short cpudone
p1_186: mov dx,offset CPUType1 ; 186
jmp short cpudone
p1_8086: mov dx,offset CPUType0 ; 8086
cpudone: mov ah,09
int 21h
.186 ; make sure we set proc back to 186
.8087 fninit ; Initialize FPU
mov _Junk,55AAh ; Set junk value
fnstsw _Junk ; Store status word
cmp _Junk,0 ; If it's not 0, no FPU
jne short p2_nofpu
fnstcw _Junk ; Store control word
mov ax,_Junk ; If the bits are not the way
and ax,103Fh ; they should be, no FPU
cmp ax,3Fh
jne short p2_nofpu

and _Junk,0FF7Fh ; Clear interrupt bit
fldcw _Junk ; Load control word
fdisi ; Disable interrupts
fstcw _Junk ; Store control word
test _Junk,80h ; If it changed, it's an 8087
jnz short p2_8087
.286 ; allowes .287 also
finit ; Re-initialize
fld1 ; Divide 1 by 0 to get
fldz ; a positive infinity
fdiv
fld st ; Get a negative infinity
fchs
fcompp ; Compare them
fstsw ax ; Store status word
sahf ; If the FPU thought that they
je short p2_287 ; were equal, it's a 287
mov dx,offset FPUType3 ; 387
finit ; Init processor
jmp short fputypeD
p2_287: mov dx,offset FPUType2 ; 287
finit ; Init processor
jmp short fputypeD
p2_8087: mov dx,offset FPUType0 ; 8087
finit ; Init processor
jmp short fputypeD
p2_nofpu: mov dx,offset FPUType
fputypeD: mov ah,09
int 21h
.186
.8087
ret


_Junk dw 00h
CPUType0 db 13,10,'You have an 8086/88 processor.$'
CPUType1 db 13,10,'You have an 186/88 processor.$'
CPUType2 db 13,10,'You have an 286 processor.$'
CPUType3 db 13,10,'You have an 386 processor.$'
CPUType4 db 13,10,'You have an 486 processor.$'
CPUType5 db 13,10,'You have an 586 or better processor.$'

FPUType db 13,10,"You don't have a math coprocessor.$"
FPUType0 db 13,10,'You have an 8087 math coprocessor.$'
FPUType2 db 13,10,'You have an 287 math coprocessor.$'
FPUType3 db 13,10,'You have an 387 or better math coprocessor.$'

CodeSeg ends
end start