📄 _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 @@Donecprocend;----------------------------------------------------------------------------; 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 @@Donecprocend;----------------------------------------------------------------------------; 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 @@Donecprocend;----------------------------------------------------------------------------; 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 @@Donecprocend;----------------------------------------------------------------------------; 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 @@Donecprocend;----------------------------------------------------------------------------; ulong _CPU_quickRDTSC(void);----------------------------------------------------------------------------; Reads the time stamp counter and returns the low order 32-bits;----------------------------------------------------------------------------cprocstart _CPU_quickRDTSC mRDTSC retcprocend;----------------------------------------------------------------------------; 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 retcprocend;----------------------------------------------------------------------------; 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 retcprocend;----------------------------------------------------------------------------; 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 partifndef flatmodel shld edx,eax,16 ; Return in DX:AXendif leave_c retcprocend;----------------------------------------------------------------------------; 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) / 0x100000ifndef flatmodel shld edx,eax,16 ; Return in DX:AXendif leave_c retcprocend;----------------------------------------------------------------------------; 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:AXendif leave_c retcprocendendcodeseg _cpuinfo END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -