📄 _cpuinfo.asm
字号:
enter_c
xor eax, eax ; Set up for CPUID instruction
mCPU_ID ; Get and save vendor ID
cmp eax, 1 ; Make sure 1 is valid input for CPUID
jl @@Fail ; We dont have the CPUID instruction
xor eax, eax
inc eax
mCPU_ID ; Get family/model/stepping/features
and eax, 0F0h
shr eax, 4 ; Isolate model
@@Done: leave_c
ret
@@Fail: xor eax,eax
jmp @@Done
cprocend
;----------------------------------------------------------------------------
; uint _CPU_getCPUIDStepping(void)
;----------------------------------------------------------------------------
; Determines the CPU type using the CPUID instruction.
;----------------------------------------------------------------------------
cprocstart _CPU_getCPUIDStepping
enter_c
xor eax, eax ; Set up for CPUID instruction
mCPU_ID ; Get and save vendor ID
cmp eax, 1 ; Make sure 1 is valid input for CPUID
jl @@Fail ; We dont have the CPUID instruction
xor eax, eax
inc eax
mCPU_ID ; Get family/model/stepping/features
and eax, 00Fh ; Isolate stepping
@@Done: leave_c
ret
@@Fail: xor eax,eax
jmp @@Done
cprocend
;----------------------------------------------------------------------------
; uint _CPU_getCPUIDFeatures(void)
;----------------------------------------------------------------------------
; Determines the CPU type using the CPUID instruction.
;----------------------------------------------------------------------------
cprocstart _CPU_getCPUIDFeatures
enter_c
xor eax, eax ; Set up for CPUID instruction
mCPU_ID ; Get and save vendor ID
cmp eax, 1 ; Make sure 1 is valid input for CPUID
jl @@Fail ; We dont have the CPUID instruction
xor eax, eax
inc eax
mCPU_ID ; Get family/model/stepping/features
mov eax, edx
@@Done: leave_c
ret
@@Fail: xor eax,eax
jmp @@Done
cprocend
;----------------------------------------------------------------------------
; uint _CPU_getCacheSize(void)
;----------------------------------------------------------------------------
; Determines the CPU cache size for Intel processors
;----------------------------------------------------------------------------
cprocstart _CPU_getCacheSize
enter_c
xor eax, eax ; Set up for CPUID instruction
mCPU_ID ; Get and save vendor ID
cmp eax,2 ; Make sure 2 is valid input for CPUID
jl @@Fail ; We dont have the CPUID instruction
mov eax,2
mCPU_ID ; Get cache descriptors
LEA_L esi,cache_id ; Get address of cache ID (-fPIC aware)
shr eax,8
mov [esi+0],eax
mov [esi+3],ebx
mov [esi+7],ecx
mov [esi+11],edx
xor eax,eax
LEA_L esi,cache_id ; Get address of cache ID (-fPIC aware)
mov edi,15
@@ScanLoop:
cmp [BYTE esi],41h
mov eax,128
je @@Done
cmp [BYTE esi],42h
mov eax,256
je @@Done
cmp [BYTE esi],43h
mov eax,512
je @@Done
cmp [BYTE esi],44h
mov eax,1024
je @@Done
cmp [BYTE esi],45h
mov eax,2048
je @@Done
inc esi
dec edi
jnz @@ScanLoop
@@Done: leave_c
ret
@@Fail: xor eax,eax
jmp @@Done
cprocend
;----------------------------------------------------------------------------
; uint _CPU_have3DNow(void)
;----------------------------------------------------------------------------
; Determines the CPU type using the CPUID instruction.
;----------------------------------------------------------------------------
cprocstart _CPU_have3DNow
enter_c
mov eax,80000000h ; Query for extended functions
mCPU_ID ; Get extended function limit
cmp eax,80000001h
jbe @@Fail ; Nope, we dont have function 800000001h
mov eax,80000001h ; Setup extended function 800000001h
mCPU_ID ; and get the information
test edx,80000000h ; Bit 31 is set if 3DNow! present
jz @@Fail ; Nope, we dont have 3DNow support
mov eax,1 ; Yep, we have 3DNow! support!
@@Done: leave_c
ret
@@Fail: xor eax,eax
jmp @@Done
cprocend
;----------------------------------------------------------------------------
; ulong _CPU_quickRDTSC(void)
;----------------------------------------------------------------------------
; Reads the time stamp counter and returns the low order 32-bits
;----------------------------------------------------------------------------
cprocstart _CPU_quickRDTSC
mRDTSC
ret
cprocend
;----------------------------------------------------------------------------
; void _CPU_runBSFLoop(ulong interations)
;----------------------------------------------------------------------------
; Runs a loop of BSF instructions for the specified number of iterations
;----------------------------------------------------------------------------
cprocstart _CPU_runBSFLoop
ARG iterations:ULONG
push _bp
mov _bp,_sp
push _bx
mov edx,[iterations]
mov eax,80000000h
mov ebx,edx
ALIGN 4
@@loop: bsf ecx,eax
dec ebx
jnz @@loop
pop _bx
pop _bp
ret
cprocend
;----------------------------------------------------------------------------
; void _CPU_readTimeStamp(CPU_largeInteger *time);
;----------------------------------------------------------------------------
; Reads the time stamp counter and returns the 64-bit result.
;----------------------------------------------------------------------------
cprocstart _CPU_readTimeStamp
mRDTSC
mov ecx,[esp+4] ; Access directly without stack frame
mov [ecx],eax
mov [ecx+4],edx
ret
cprocend
;----------------------------------------------------------------------------
; ulong _CPU_diffTime64(CPU_largeInteger *t1,CPU_largeInteger *t2,CPU_largeInteger *t)
;----------------------------------------------------------------------------
; Computes the difference between two 64-bit numbers.
;----------------------------------------------------------------------------
cprocstart _CPU_diffTime64
ARG t1:DPTR, t2:DPTR, t:DPTR
enter_c
mov ecx,[t2]
mov eax,[ecx] ; EAX := t2.low
mov ecx,[t1]
sub eax,[ecx]
mov edx,eax ; EDX := low difference
mov ecx,[t2]
mov eax,[ecx+4] ; ECX := t2.high
mov ecx,[t1]
sbb eax,[ecx+4] ; EAX := high difference
mov ebx,[t] ; Store the result
mov [ebx],edx ; Store low part
mov [ebx+4],eax ; Store high part
mov eax,edx ; Return low part
ifndef flatmodel
shld edx,eax,16 ; Return in DX:AX
endif
leave_c
ret
cprocend
;----------------------------------------------------------------------------
; ulong _CPU_calcMicroSec(CPU_largeInteger *count,ulong freq);
;----------------------------------------------------------------------------
; Computes the value in microseconds for the elapsed time with maximum
; precision. The formula we use is:
;
; us = (((diff * 0x100000) / freq) * 1000000) / 0x100000)
;
; The power of two multiple before the first divide allows us to scale the
; 64-bit difference using simple shifts, and then the divide brings the
; final result into the range to fit into a 32-bit integer.
;----------------------------------------------------------------------------
cprocstart _CPU_calcMicroSec
ARG count:DPTR, freq:ULONG
enter_c
mov ecx,[count]
mov eax,[ecx] ; EAX := low part
mov edx,[ecx+4] ; EDX := high part
shld edx,eax,20
shl eax,20 ; diff * 0x100000
div [DWORD freq] ; (diff * 0x100000) / freq
mov ecx,1000000
xor edx,edx
mul ecx ; ((diff * 0x100000) / freq) * 1000000)
shrd eax,edx,20 ; ((diff * 0x100000) / freq) * 1000000) / 0x100000
ifndef flatmodel
shld edx,eax,16 ; Return in DX:AX
endif
leave_c
ret
cprocend
;----------------------------------------------------------------------------
; ulong _CPU_mulDiv(ulong a,ulong b,ulong c);
;----------------------------------------------------------------------------
; Computes the following with 64-bit integer precision:
;
; result = (a * b) / c
;
;----------------------------------------------------------------------------
cprocstart _CPU_mulDiv
ARG a:ULONG, b:ULONG, c:ULONG
enter_c
mov eax,[a]
imul [ULONG b]
idiv [ULONG c]
ifndef flatmodel
shld edx,eax,16 ; Return in DX:AX
endif
leave_c
ret
cprocend
endcodeseg _cpuinfo
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -