阅读:3532回复:7
怎样在C语言中读出CPU或硬盘序列号,网卡地址?
朋友:请教怎样在C语言中读出CPU或硬盘序列号,网卡地址?请回
hq.li@bjpeu.edu.cn 万分感谢!! |
|
沙发#
发布于:2004-04-09 21:20
网上有库函数的。
|
|
|
板凳#
发布于:2004-04-12 09:31
朋友:请教怎样在C语言中读出CPU或硬盘序列号,网卡地址?请回 读出CPU序列号,下面的代码来自Intel? Processor Identification and the CPUID Instruction 不过是汇编的,希望对你有帮助。 CPU_ID MACRO db 0fh ; Hardcoded CPUID instruction db 0a2h ENDM data public _cpu_type public _fpu_type public _v86_flag public _cpuid_flag public _intel_CPU public _vendor_id public _cpu_signature public _features_ecx public _features_edx public _features_ebx public _cache_eax public _cache_ebx public _cache_ecx public _cache_edx public _sep_flag public _brand_string _cpu_type db 0 _fpu_type db 0 _v86_flag db 0 _cpuid_flag db 0 _intel_CPU db 0 _sep_flag db 0 _vendor_id db \"------------\" intel_id db \"GenuineIntel\" _cpu_signature dd 0 _features_ecx dd 0 _features_edx dd 0 _features_ebx dd 0 _cache_eax dd 0 _cache_ebx dd 0 _cache_ecx dd 0 _cache_edx dd 0 fp_status dw 0 _brand_string db 48 dup (0) .code ; ; comment this line for 32-bit segments ; .8086 ; ; uncomment this line for 32-bit segments ; ; .386 ********************************************************************* public _get_cpu_type _get_cpu_type proc ; This procedure determines the type of processor in a system ; and sets the _cpu_type variable with the appropriate ; value. If the CPUID instruction is available, it is used ; to determine more specific details about the processor. ; All registers are used by this procedure, none are preserved. ; To avoid AC faults, the AM bit in CR0 must not be set. ; Intel 8086 processor check ; Bits 12-15 of the FLAGS register are always set on the ; 8086 processor. ; ; For 32-bit segments comment the following lines down to the next ; comment line that says \"STOP\" ; check_8086: pushf ; push original FLAGS pop ax ; get original FLAGS mov cx, ax ; save original FLAGS and ax, 0fffh ; clear bits 12-15 in FLAGS push ax ; save new FLAGS value on stack popf ; replace current FLAGS value pushf ; get new FLAGS pop ax ; store new FLAGS in AX and ax, 0f000h ; if bits 12-15 are set, then cmp ax, 0f000h ; processor is an 8086/8088 mov _cpu_type, 0 ; turn on 8086/8088 flag jne check_80286 ; go check for 80286 push sp ; double check with push sp pop dx ; if value pushed was different cmp dx, sp ; means it\'s really an 8086 jne end_cpu_type ; jump if processor is 8086/8088 mov _cpu_type, 10h ; indicate unknown processor jmp end_cpu_type ; Intel 286 processor check ; Bits 12-15 of the FLAGS register are always clear on the ; Intel 286 processor in real-address mode. .286 check_80286: smsw ax ; save machine status word and ax, 1 ; isolate PE bit of MSW mov _v86_flag, al ; save PE bit to indicate V86 or cx, 0f000h ; try to set bits 12-15 push cx ; save new FLAGS value on stack popf ; replace current FLAGS value pushf ; get new FLAGS pop ax ; store new FLAGS in AX and ax, 0f000h ; if bits 12-15 are clear mov _cpu_type, 2 ; processor=80286, turn on 80286 flag jz end_cpu_type ; jump if processor is 80286 ; Intel386 processor check ; The AC bit, bit #18, is a new bit introduced in the EFLAGS ; register on the Intel486 processor to generate alignment ; faults. ; This bit cannot be set on the Intel386 processor. .386 ; ; \"STOP\" ; ; ; it is safe to use 386 instructions check_80386: pushfd ; push original EFLAGS pop eax ; get original EFLAGS mov ecx, eax ; save original EFLAGS xor eax, 40000h ; flip AC bit in EFLAGS push eax ; save new EFLAGS value on stack popfd ; replace current EFLAGS value pushfd ; get new EFLAGS pop eax ; store new EFLAGS in EAX xor eax, ecx ; can\'t toggle AC bit, processor=80386 mov _cpu_type, 3 ; turn on 80386 processor flag jz end_cpu_type ; jump if 80386 processor push ecx popfd ; restore AC bit in EFLAGS first ; Intel486 processor check ; Checking for ability to set/clear ID flag (Bit 21) in EFLAGS ; which indicates the presence of a processor with the CPUID ; instruction. .486 check_80486: mov _cpu_type, 4 ; turn on 80486 processor flag mov eax, ecx ; get original EFLAGS xor eax, 200000h ; flip ID bit in EFLAGS push eax ; save new EFLAGS value on stack popfd ; replace current EFLAGS value pushfd ; get new EFLAGS pop eax ; store new EFLAGS in EAX xor eax, ecx ; can\'t toggle ID bit, je end_cpu_type ; processor=80486 ; Execute CPUID instruction to determine vendor, family, ; model, stepping and features. For the purpose of this ; code, only the initial set of CPUID information is saved. mov _cpuid_flag, 1 ; flag indicating use of CPUID inst. push ebx ; save registers push esi push edi mov eax, 0 ; set up for CPUID instruction CPU_ID ; get and save vendor ID mov dword ptr _vendor_id, ebx mov dword ptr _vendor_id[+4], edx mov dword ptr _vendor_id[+8], ecx cmp dword ptr intel_id, ebx jne end_cpuid_type cmp dword ptr intel_id[+4], edx jne end_cpuid_type cmp dword ptr intel_id[+8], ecx jne end_cpuid_type ; if not equal, not an Intel processor mov _intel_CPU, 1 ; indicate an Intel processor cmp eax, 1 ; make sure 1 is valid input for CPUID jl end_cpuid_type ; if not, jump to end mov eax, 1 CPU_ID ; get family/model/stepping/features mov _cpu_signature, eax mov _features_ebx, ebx mov _features_edx, edx mov _features_ecx, ecx shr eax, 8 ; isolate family and eax, 0fh mov _cpu_type, al ; set _cpu_type with family ; Execute CPUID instruction to determine the cache descriptor ; information. mov eax, 0 ; set up to check the EAX value CPU_ID cmp ax, 2 ; Are cache descriptors supported? jl end_cpuid_type mov eax, 2 ; set up to read cache descriptor CPU_ID cmp al, 1 ; Is one iteration enough to obtain jne end_cpuid_type ; cache information? ; This code supports one iteration ; only. mov _cache_eax, eax ; store cache information mov _cache_ebx, ebx ; NOTE: for future processors, CPUID mov _cache_ecx, ecx ; instruction may need to be run more mov _cache_edx, edx ; than once to get complete cache ; information mov eax, 80000000h ; check if brand string is supported CPU_ID cmp eax, 80000000h jbe end_cpuid_type ; take jump if not supported mov di, offset _brand_string mov eax, 80000002h ; get first 16 bytes of brand string CPU_ID mov dword ptr [di], eax ; save bytes 0 .. 15 mov dword ptr [di+4], ebx mov dword ptr [di+8], ecx mov dword ptr [di+12], edx add di, 16 mov eax, 80000003h CPU_ID mov dword ptr [di], eax ; save bytes 16 .. 31 mov dword ptr [di+4], ebx mov dword ptr [di+8], ecx mov dword ptr [di+12], edx add di, 16 mov eax, 80000004h CPU_ID mov dword ptr [di], eax ; save bytes 32 .. 47 mov dword ptr [di+4], ebx mov dword ptr [di+8], ecx mov dword ptr [di+12], edx end_cpuid_type: pop edi ; restore registers pop esi pop ebx ; ; comment this line for 32-bit segments ; .8086 end_cpu_type: ret _get_cpu_type endp ********************************************************************* public _get_fpu_type _get_fpu_type proc ; This procedure determines the type of FPU in a system ; and sets the _fpu_type variable with the appropriate value. ; All registers are used by this procedure, none are preserved. ; Coprocessor check ; The algorithm is to determine whether the floating-point ; status and control words are present. If not, no ; coprocessor exists. If the status and control words can ; be saved, the correct coprocessor is then determined ; depending on the processor type. The Intel386 processor can ; work with either an Intel287 NDP or an Intel387 NDP. ; The infinity of the coprocessor must be checked to determine ; the correct coprocessor type. fninit ; reset FP status word mov fp_status, 5a5ah ; initialize temp word to non-zero fnstsw fp_status ; save FP status word mov ax, fp_status ; check FP status word cmp al, 0 ; was correct status written mov _fpu_type, 0 ; no FPU present jne end_fpu_type check_control_word: fnstcw fp_status ; save FP control word mov ax, fp_status ; check FP control word and ax, 103fh ; selected parts to examine cmp ax, 3fh ; was control word correct mov _fpu_type, 0 jne end_fpu_type ; incorrect control word, no FPU mov _fpu_type, 1 ; 80287/80387 check for the Intel386 processor check_infinity: cmp _cpu_type, 3 jne end_fpu_type fld1 ; must use default control from FNINIT fldz ; form infinity fdiv ; 8087/Intel287 NDP say +inf = -inf fld st ; form negative infinity fchs ; Intel387 NDP says +inf <> -inf fcompp ; see if they are the same fstsw fp_status ; look at status from FCOMPP mov ax, fp_status mov _fpu_type, 2 ; store Intel287 NDP for FPU type sahf ; see if infinities matched jz end_fpu_type ; jump if 8087 or Intel287 is present mov _fpu_type, 3 ; store Intel387 NDP for FPU type end_fpu_type: ret _get_fpu_type endp end [编辑 - 4/12/04 by BlackJack] |
|
地板#
发布于:2004-04-14 14:32
MAC 地址在注册表中有
打开注册表编辑器,找到HKEY_LOCAL_MACHINE\\system\\Currentcontrolset\\services\\classes\\net\\0000、0001、0002, DriverDesc内容为你要修改的网卡的描述。NetworkAddress为你要的MAC地址,要连续写。如5254ab5559e1 |
|
|
地下室#
发布于:2004-04-14 14:33
可以用程序改写以上键值
|
|
|
5楼#
发布于:2004-04-16 11:25
title \"Processor type and stepping detection\"
;++ ; ; Copyright (c) 1989 Microsoft Corporation ; ; Module Name: ; ; cpu.asm ; ; Abstract: ; ; This module implements the assembley code necessary to determine ; cpu type and stepping information. ; ; Author: ; ; Shie-Lin Tzong (shielint) 28-Oct-1991. ; Some of the code is extracted from Cruiser (mainly, ; the code to determine 386 stepping.) ; ; Environment: ; ; 80x86 ; ; Revision History: ; ;-- .xlist include i386\\cpu.inc include ks386.inc include callconv.inc include mac386.inc .list ; ; constant for i386 32-bit multiplication test ; MULTIPLIER equ 00000081h MULTIPLICAND equ 0417a000h RESULT_HIGH equ 00000002h RESULT_LOW equ 0fe7a000h ; ; Constants for Floating Point test ; REALLONG_LOW equ 00000000 REALLONG_HIGH equ 3FE00000h PSEUDO_DENORMAL_LOW equ 00000000h PSEUDO_DENORMAL_MID equ 80000000h PSEUDO_DENORMAL_HIGH equ 0000h .586p INIT SEGMENT DWORD PUBLIC \'CODE\' ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING ;++ ; ; USHORT ; KiSetProcessorType ( ; VOID ; ) ; ; Routine Description: ; ; This function determines type of processor (80486, 80386), ; and it\'s corrisponding stepping. The results are saved in ; the current processor\'s PRCB. ; ; Arguments: ; ; None. ; ; Return Value: ; ; Prcb->CpuType ; 3, 4, 5, ... 3 = 386, 4 = 486, etc.. ; ; Prcb->CpuStep is encoded as follows: ; lower byte as stepping # ; upper byte as stepping letter (0=a, 1=b, 2=c, ...) ; ; (ax) = x86h or 0 if unrecongnized processor. ; ;-- cPublicProc _KiSetProcessorType,0 mov byte ptr fs:PcPrcbData.PbCpuID, 0 push edi push esi push ebx ; Save C registers mov eax, cr0 push eax pushfd ; save Cr0 & flags pop ebx ; Get flags into eax push ebx ; Save original flags mov ecx, ebx xor ecx, EFLAGS_ID ; flip ID bit push ecx popfd ; load it into flags pushfd ; re-save flags pop ecx ; get flags into eax cmp ebx, ecx ; did bit stay flipped? jne short cpu_has_cpuid ; Yes, go use CPUID cpuid_unsupported: pop ebx ; Get flags into eax push ebx ; Save original flags mov ecx, ebx xor ecx, EFLAGS_AC ; flip AC bit push ecx popfd ; load it into flags pushfd ; re-save flags pop ecx ; get flags into eax cmp ebx, ecx ; did bit stay flipped? je short cpu_is_386 ; No, then this is a 386 cpu_is_486: mov byte ptr fs:PcPrcbData.PbCpuType, 4h ; Save CPU Type call Get486Stepping jmp cpu_save_stepping cpu_is_386: mov byte ptr fs:PcPrcbData.PbCpuType, 3h ; Save CPU Type call Get386Stepping jmp cpu_save_stepping cpu_has_cpuid: or ebx, EFLAGS_ID push ebx popfd ; Make sure ID bit is set mov ecx, fs:PcIdt ; Address of IDT push dword ptr [ecx+30h] ; Save Trap06 handler incase push dword ptr [ecx+34h] ; the CPUID instruction faults mov eax, offset CpuIdTrap6Handler mov word ptr [ecx+30h], ax ; Set LowWord shr eax, 16 mov word ptr [ecx+36h], ax ; Set HighWord mov eax, 0 ; argument to CPUID cpuid ; Uses eax, ebx, ecx, edx mov ecx, fs:PcIdt ; Address of IDT pop dword ptr [ecx+34h] ; restore trap6 handler pop dword ptr [ecx+30h] cmp eax, 1 ; make sure level 1 is supported jc short cpuid_unsupported ; no, then punt ; Get the family and stepping (cpuid fn=1). Format returned is ; 3 2 1 ; 10987654321098765432109876543210 ; -------------------------------- ; ppffffmmmmssss ; where ; pp = Processor Type ; ffff = Family ; mmmm = Model ; ssss = Stepping ; ; This is transformed and saved in the PRCB as ; ; PRCB->CpuStep = 0000mmmm0000ssss v v ; ->CpuID = 00000001 | | v ; ->CpuType = 0000ffff | | | v ; | | | | ; ie the dword that contains all this looks like 0M0S010F ; mov eax, 1 ; get the family and stepping cpuid mov ebx, eax and eax, 0F0h ; (eax) = Model shl eax, 4 mov al, bl and eax, 0F0Fh ; (eax) = Model[15:8] | Step[7:0] and ebx, 0F00h ; (bh) = CpuType mov byte ptr fs:PcPrcbData.PbCpuID, 1 ; Has ID support mov byte ptr fs:PcPrcbData.PbCpuType, bh ; Save CPU Type cpu_save_stepping: mov word ptr fs:PcPrcbData.PbCpuStep, ax ; Save CPU Stepping popfd ; Restore flags pop eax mov cr0, eax pop ebx pop esi pop edi stdRET _KiSetProcessorType cpuid_trap: mov ecx, fs:PcIdt ; Address of IDT pop dword ptr [ecx+34h] ; restore trap6 handler pop dword ptr [ecx+30h] jmp cpuid_unsupported ; Go get processor information stdENDP _KiSetProcessorType ;++ ; ; BOOLEAN ; CpuIdTrap6 ( ; VOID ; ) ; ; Routine Description: ; ; Temporary int 6 handler - assumes the cause of the exception was the ; attempted CPUID instruction. ; ; Arguments: ; ; None. ; ; Return Value: ; ; none. ; ;-- CpuIdTrap6Handler proc mov [esp].IretEip,offset cpuid_trap iretd CpuIdTrap6Handler endp ;++ ; ; USHORT ; Get386Stepping ( ; VOID ; ) ; ; Routine Description: ; ; This function determines cpu stepping for i386 CPU stepping. ; ; Arguments: ; ; None. ; ; Return Value: ; ; [ax] - Cpu stepping. ; 0 = A, 1 = B, 2 = C, ... ; ;-- public Get386Stepping Get386Stepping proc call MultiplyTest ; Perform mutiplication test jnc short G3s00 ; if nc, muttest is ok mov ax, 0 ret G3s00: call Check386B0 ; Check for B0 stepping jnc short G3s05 ; if nc, it\'s B1/later mov ax, 100h ; It is B0/earlier stepping ret G3s05: call Check386D1 ; Check for D1 stepping jc short G3s10 ; if c, it is NOT D1 mov ax, 301h ; It is D1/later stepping ret G3s10: mov ax, 101h ; assume it is B1 stepping ret Get386Stepping endp ;++ ; ; USHORT ; Get486Stepping ( ; VOID ; ) ; ; Routine Description: ; ; This function determines cpu stepping for i486 CPU type. ; ; Arguments: ; ; None. ; ; Return Value: ; ; [ax] - Cpu stepping. For example, [ax] = D0h for D0 stepping. ; ;-- public Get486Stepping Get486Stepping proc call Check486AStepping ; Check for A stepping jnc short G4s00 ; if nc, it is NOT A stepping mov ax, 0 ; set to A stepping ret G4s00: call Check486BStepping ; Check for B stepping jnc short G4s10 ; if nc, it is NOT a B stepping mov ax, 100h ; set to B stepping ret ; ; Before we test for 486 C/D step, we need to make sure NPX is present. ; Because the test uses FP instruction to do the detection. ; G4s10: call _KiIsNpxPresent ; Check if cpu has coprocessor support? or ax, ax jz short G4s15 ; it is actually 486sx call Check486CStepping ; Check for C stepping jnc short G4s20 ; if nc, it is NOT a C stepping G4s15: mov ax, 200h ; set to C stepping ret G4s20: mov ax, 300h ; Set to D stepping ret Get486Stepping endp ;++ ; ; BOOLEAN ; Check486AStepping ( ; VOID ; ) ; ; Routine Description: ; ; This routine checks for 486 A Stepping. ; ; It takes advantage of the fact that on the A-step of the i486 ; processor, the ET bit in CR0 could be set or cleared by software, ; but was not used by the hardware. On B or C -step, ET bit in CR0 ; is now hardwired to a \"1\" to force usage of the 386 math coprocessor ; protocol. ; ; Arguments: ; ; None. ; ; Return Value: ; ; Carry Flag clear if B or later stepping. ; Carry Flag set if A or earlier stepping. ; ;-- public Check486AStepping Check486AStepping proc near mov eax, cr0 ; reset ET bit in cr0 and eax, NOT CR0_ET mov cr0, eax mov eax, cr0 ; get cr0 back test eax, CR0_ET ; if ET bit still set? jnz short cas10 ; if nz, yes, still set, it\'s NOT A step stc ret cas10: clc ret Check486AStepping endp ;++ ; ; BOOLEAN ; Check486BStepping ( ; VOID ; ) ; ; Routine Description: ; ; This routine checks for 486 B Stepping. ; ; On the i486 processor, the \"mov to/from DR4/5\" instructions were ; aliased to \"mov to/from DR6/7\" instructions. However, the i486 ; B or earlier steps generate an Invalid opcode exception when DR4/5 ; are used with \"mov to/from special register\" instruction. ; ; Arguments: ; ; None. ; ; Return Value: ; ; Carry Flag clear if C or later stepping. ; Carry Flag set if B stepping. ; ;-- public Check486BStepping Check486BStepping proc push ebx mov ebx, fs:PcIdt ; Address of IDT push dword ptr [ebx+30h] push dword ptr [ebx+34h] ; Save Trap06 handler mov eax, offset Temporary486Int6 mov word ptr [ebx+30h], ax ; Set LowWord shr eax, 16 mov word ptr [ebx+36h], ax ; Set HighWord c4bs50: db 0fh, 21h, 0e0h ; mov eax, DR4 nop nop nop nop nop clc ; it is C step jmp short c4bs70 c4bs60: stc ; it\'s B step c4bs70: pop dword ptr [ebx+34h] ; restore old int 6 vector pop dword ptr [ebx+30h] pop ebx ret ret Check486BStepping endp ;++ ; ; BOOLEAN ; Temporary486Int6 ( ; VOID ; ) ; ; Routine Description: ; ; Temporary int 6 handler - assumes the cause of the exception was the ; attempted execution of an mov to/from DR4/5 instruction. ; ; Arguments: ; ; None. ; ; Return Value: ; ; none. ; ;-- Temporary486Int6 proc mov [esp].IretEIp,offset c4bs60 ; set EIP to stc instruction iretd Temporary486Int6 endp ;++ ; ; BOOLEAN ; Check486CStepping ( ; VOID ; ) ; ; Routine Description: ; ; This routine checks for 486 C Stepping. ; ; This routine takes advantage of the fact that FSCALE produces ; wrong result with Denormal or Pseudo-denormal operand on 486 ; C and earlier steps. ; ; If the value contained in ST(1), second location in the floating ; point stack, is between 1 and 11, and the value in ST, top of the ; floating point stack, is either a pseudo-denormal number or a ; denormal number with the underflow exception unmasked, the FSCALE ; instruction produces an incorrect result. ; ; Arguments: ; ; None. ; ; Return Value: ; ; Carry Flag clear if D or later stepping. ; Carry Flag set if C stepping. ; ;-- FpControl equ [ebp - 2] RealLongSt1 equ [ebp - 10] PseudoDenormal equ [ebp - 20] FscaleResult equ [ebp - 30] public Check486CStepping Check486CStepping proc push ebp mov ebp, esp sub esp, 30 ; Allocate space for temp real variables mov eax, cr0 ; Don\'t trap while doing math and eax, NOT (CR0_ET+CR0_MP+CR0_TS+CR0_EM) mov cr0, eax ; ; Initialize the local FP variables to predefined values. ; RealLongSt1 = 1.0 * (2 ** -1) = 0.5 in normalized double precision FP form ; PseudoDenormal = a unsupported format by IEEE. ; Sign bit = 0 ; Exponent = 000000000000000B ; Significand = 100000...0B ; FscaleResult = The result of FSCALE instruction. Depending on 486 step, ; the value will be different: ; Under C and earlier steps, 486 returns the original value ; in ST as the result. The correct returned value should be ; original significand and an exponent of 0...01. ; mov dword ptr RealLongSt1, REALLONG_LOW mov dword ptr RealLongSt1 + 4, REALLONG_HIGH mov dword ptr PseudoDenormal, PSEUDO_DENORMAL_LOW mov dword ptr PseudoDenormal + 4, PSEUDO_DENORMAL_MID mov word ptr PseudoDenormal + 8, PSEUDO_DENORMAL_HIGH .387 fnstcw FpControl ; Get FP control word fwait or word ptr FpControl, 0FFh ; Mask all the FP exceptions fldcw FpControl ; Set FP control fld qword ptr RealLongSt1 ; 0 < ST(1) = RealLongSt1 < 1 fld tbyte ptr PseudoDenormal; Denormalized operand. Note, i486 ; won\'t report denormal exception ; on \'FLD\' instruction. ; ST(0) = Extended Denormalized operand fscale ; try to trigger 486Cx errata fstp tbyte ptr FscaleResult ; Store ST(0) in FscaleResult cmp word ptr FscaleResult + 8, PSEUDO_DENORMAL_HIGH ; Is Exponent changed? jz short c4ds00 ; if z, no, it is C step clc jmp short c4ds10 c4ds00: stc c4ds10: mov esp, ebp pop ebp ret Check486CStepping endp ;++ ; ; BOOLEAN ; Check386B0 ( ; VOID ; ) ; ; Routine Description: ; ; This routine checks for 386 B0 or earlier stepping. ; ; It takes advantage of the fact that the bit INSERT and ; EXTRACT instructions that existed in B0 and earlier versions of the ; 386 were removed in the B1 stepping. When executed on the B1, INSERT ; and EXTRACT cause an int 6 (invalid opcode) exception. This routine ; can therefore discriminate between B1/later 386s and B0/earlier 386s. ; It is intended to be used in sequence with other checks to determine ; processor stepping by exercising specific bugs found in specific ; steppings of the 386. ; ; Arguments: ; ; None. ; ; Return Value: ; ; Carry Flag clear if B1 or later stepping ; Carry Flag set if B0 or prior ; ;-- Check386B0 proc push ebx mov ebx, fs:PcIdt ; Address of IDT push dword ptr [ebx+30h] push dword ptr [ebx+34h] ; Save Trap06 handler mov eax, offset TemporaryInt6 mov word ptr [ebx+30h], ax ; Set LowWord shr eax, 16 mov word ptr [ebx+36h], ax ; Set HighWord ; ; Attempt execution of Extract Bit String instruction. Execution on ; B0 or earlier with length (CL) = 0 will return 0 into the destination ; (CX in this case). Execution on B1 or later will fail either due to ; taking the invalid opcode trap, or if the opcode is valid, we don\'t ; expect CX will be zeroed by any new instruction supported by newer ; steppings. The dummy int 6 handler will clears the Carry Flag and ; returns execution to the appropriate label. If the instruction ; actually executes, CX will *probably* remain unchanged in any new ; stepping that uses the opcode for something else. The nops are meant ; to handle newer steppings with an unknown instruction length. ; xor eax,eax mov edx,eax mov ecx,0ff00h ; Extract length (CL) == 0, (CX) != 0 b1c50: db 0fh, 0a6h, 0cah ; xbts cx,dx,ax,cl nop nop nop nop nop stc ; assume B0 jecxz short b1c70 ; jmp if B0 b1c60: clc b1c70: pop dword ptr [ebx+34h] ; restore old int 6 vector pop dword ptr [ebx+30h] pop ebx ret Check386B0 endp ;++ ; ; BOOLEAN ; TemporaryInt6 ( ; VOID ; ) ; ; Routine Description: ; ; Temporary int 6 handler - assumes the cause of the exception was the ; attempted execution of an XTBS instruction. ; ; Arguments: ; ; None. ; ; Return Value: ; ; none. ; ;-- TemporaryInt6 proc mov [esp].IretEip,offset b1c60 ; set IP to clc instruction iretd TemporaryInt6 endp ;++ ; ; BOOLEAN ; Check386D1 ( ; VOID ; ) ; ; Routine Description: ; ; This routine checks for 386 D1 Stepping. ; ; It takes advantage of the fact that on pre-D1 386, if a REPeated ; MOVS instruction is executed when single-stepping is enabled, ; a single step trap is taken every TWO moves steps, but should ; occuu each move step. ; ; NOTE: This routine cannot distinguish between a D0 stepping and a D1 ; stepping. If a need arises to make this distinction, this routine ; will need modification. D0 steppings will be recognized as D1. ; ; Arguments: ; ; None. ; ; Return Value: ; ; Carry Flag clear if D1 or later stepping ; Carry Flag set if B1 or prior ; ;-- Check386D1 proc push ebx mov ebx, fs:PcIdt ; Address of IDT push dword ptr [ebx+08h] push dword ptr [ebx+0ch] ; Save Trap01 handler mov eax, offset TemporaryInt1 mov word ptr [ebx+08h], ax ; Set LowWord shr eax, 16 mov word ptr [ebx+0eh], ax ; Set HighWord ; ; Attempt execution of rep movsb instruction with the Trace Flag set. ; Execution on B1 or earlier with length (CX) > 1 will trace over two ; iterations before accepting the trace trap. Execution on D1 or later ; will accept the trace trap after a single iteration. The dummy int 1 ; handler will return execution to the instruction following the movsb ; instruction. Examination of (CX) will reveal the stepping. ; sub esp,4 ; make room for target of movsb mov esi, offset TemporaryInt1 ; (ds:esi) -> some present data mov edi,esp mov ecx,2 ; 2 iterations pushfd or dword ptr [esp], EFLAGS_TF popfd ; cause a single step trap rep movsb d1c60: add esp,4 ; clean off stack pop dword ptr [ebx+0ch] ; restore old int 1 vector pop dword ptr [ebx+08h] stc ; assume B1 jecxz short d1cx ; jmp if <= B1 clc ; else clear carry to indicate >= D1 d1cx: pop ebx ret Check386D1 endp ;++ ; ; BOOLEAN ; TemporaryInt1 ( ; VOID ; ) ; ; Routine Description: ; ; Temporary int 1 handler - assumes the cause of the exception was ; trace trap at the above rep movs instruction. ; ; Arguments: ; ; (esp)->eip of trapped instruction ; cs of trapped instruction ; eflags of trapped instruction ; ;-- TemporaryInt1 proc and [esp].IretEFlags,not EFLAGS_TF ; clear caller\'s Trace Flag mov [esp].IretEip,offset d1c60 ; set IP to next instruction iretd TemporaryInt1 endp ;++ ; ; BOOLEAN ; MultiplyTest ( ; VOID ; ) ; ; Routine Description: ; ; This routine checks the 386 32-bit multiply instruction. ; The reason for this check is because some of the i386 fail to ; perform this instruction. ; ; Arguments: ; ; None. ; ; Return Value: ; ; Carry Flag clear on success ; Carry Flag set on failure ; ;-- ; MultiplyTest proc xor cx,cx ; 64K times is a nice round number mlt00: push cx call Multiply ; does this chip\'s multiply work? pop cx jc short mltx ; if c, No, exit loop mlt00 ; if nc, YEs, loop to try again clc mltx: ret MultiplyTest endp ;++ ; ; BOOLEAN ; Multiply ( ; VOID ; ) ; ; Routine Description: ; ; This routine performs 32-bit multiplication test which is known to ; fail on bad 386s. ; ; Note, the supplied pattern values must be used for consistent results. ; ; Arguments: ; ; None. ; ; Return Value: ; ; Carry Flag clear on success. ; Carry Flag set on failure. ; ;-- Multiply proc mov ecx, MULTIPLIER mov eax, MULTIPLICAND mul ecx cmp edx, RESULT_HIGH ; Q: high order answer OK ? stc ; assume failure jnz short mlpx ; N: exit with error cmp eax, RESULT_LOW ; Q: low order answer OK ? stc ; assume failure jnz short mlpx ; N: exit with error clc ; indicate success mlpx: ret Multiply endp ;++ ; ; BOOLEAN ; KiIsNpxPresent( ; VOID ; ); ; ; Routine Description: ; ; This routine determines if there is any Numeric coprocessor ; present. ; ; Note that we do NOT determine its type (287, 387). ; This code is extracted from Intel book. ; ; Arguments: ; ; None. ; ; Return: ; ; TRUE - If NPX is present. Else a value of FALSE is returned. ; Sets CR0 NPX bits accordingly. ; ;-- cPublicProc _KiIsNpxPresent,0 push ebp ; Save caller\'s bp mov eax, cr0 and eax, NOT (CR0_ET+CR0_MP+CR0_TS+CR0_EM) mov cr0, eax xor edx, edx .287 fninit ; Initialize NPX mov ecx, 5A5A5A5Ah ; Put non-zero value push ecx ; into the memory we are going to use mov ebp, esp fnstsw word ptr [ebp] ; Retrieve status - must use non-wait cmp byte ptr [ebp], 0 ; All bits cleared by fninit? jne Inp10 or eax, CR0_ET mov edx, 1 cmp fs:PcPrcbData.PbCpuType, 3h jbe Inp10 or eax, CR0_NE Inp10: or eax, CR0_EM+CR0_TS ; During Kernel Initialization set ; the EM bit mov cr0, eax pop eax ; clear scratch value pop ebp ; Restore caller\'s bp mov eax, edx stdRet _KiIsNpxPresent stdENDP _KiIsNpxPresent ;++ ; ; VOID ; CPUID ( ; ULONG InEax, ; PULONG OutEax, ; PULONG OutEbx, ; PULONG OutEcx, ; PULONG OutEdx ; ); ; ; Routine Description: ; ; Executes the CPUID instruction and returns the registers from it ; ; Only available at INIT time ; ; Arguments: ; ; Return Value: ; ;-- cPublicProc _CPUID,5 push ebx push esi mov eax, [esp+12] cpuid mov esi, [esp+16] ; return EAX mov [esi], eax mov esi, [esp+20] ; return EBX mov [esi], ebx mov esi, [esp+24] ; return ECX mov [esi], ecx mov esi, [esp+28] ; return EDX mov [esi], edx pop esi pop ebx stdRET _CPUID stdENDP _CPUID ;++ ; ; LONGLONG ; RDTSC ( ; VOID ; ); ; ; Routine Description: ; ; Arguments: ; ; Return Value: ; ;-- cPublicProc _RDTSC rdtsc stdRET _RDTSC stdENDP _RDTSC INIT ENDS _TEXT SEGMENT DWORD PUBLIC \'CODE\' ; Put IdleLoop in text section ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING ;++ ; ; ULONGLONG ; FASTCALL ; RDMSR ( ; IN ULONG MsrRegister ; ); ; ; Routine Description: ; ; Arguments: ; ; Return Value: ; ;-- cPublicFastCall RDMSR, 1 rdmsr fstRET RDMSR fstENDP RDMSR ;++ ; ; VOID ; WRMSR ( ; IN ULONG MsrRegister ; IN LONGLONG MsrValue ; ); ; ; Routine Description: ; ; Arguments: ; ; Return Value: ; ;-- cPublicProc _WRMSR, 3 mov ecx, [esp+4] mov eax, [esp+8] mov edx, [esp+12] wrmsr stdRET _WRMSR stdENDP _WRMSR ;++ ; ; VOID ; KeYieldProcessor ( ; VOID ; ); ; ; Routine Description: ; ; Yields a thread of the processor ; ; Arguments: ; ; Return Value: ; ;-- cPublicProc _KeYieldProcessor YIELD stdRET _KeYieldProcessor stdENDP _KeYieldProcessor _TEXT ENDS END |
|
6楼#
发布于:2004-07-25 12:10
BLACKJACK 和MAKESHI这两个新手能否将你提供的代码打包成RAR文件上传上来呀,我看的好累.
|
|
7楼#
发布于:2004-09-01 10:04
库函数怎找?
|
|