您当前位置: 圣才学习网首页 >> IT类 >> 编程技术库

DOS汇编源码系列教程——chips

扫码手机阅读
用圣才电子书APP或微信扫一扫,在手机上阅读本文,也可分享给你的朋友。
评论(0
来源:网络 作者:未知
这个都是过去DOS时代的汇编源码,虽然已经过去了,但是对于学习汇编还是有帮助的,汇编语言只是程序员一门基础语言,大多人掌握即可,不一定要深入研究.......
;  calling convention:
;
;    int chips( void );
;
;  returns:
;
;    tucked away neatly in your AX....
;
;    you get back  8x if an 8088/8086
;           18x if an 80186/80188
;           28x if an 80286
;           38x if an 80386
;           20x for a NEC V20/V30
;        AND
;           xx0 if NO NDP is found
;           xx1 if an 8087
;           xx2 if an 80287
;           xx3 for an 80387
;
;  OR.....
;
;  >>> A return of 280 means you got an 80286 machine with no NDP, <<<
;  >>> 383 means you have an 80386/80387 rig to work with, and a  <<<
;  >>> return of 81 sez that you have 8088/8086 CPU with an 8087. <<<
;  >>> A 200 tells you that you got an NEC V20/V30 without an NDP. <<<
;  >>> ETC., Etc., etc.                      <<<
;
;  NOTE:
;
;    There are lotsa ways of handling the way this function returns
;    it's data. For my purposes, I have elected this one because
;    it requires only int arithmetic on the caller's end to extract
;    all the info I need from the return value. I think that I'm
;    well enough 'commented' in the following code so that you will
;    be able to tinker and Putz until you find the best return tech-
;    nique for Ur purposes without having to reinvent the wheel.
;
;   >>>>    Please see TEST.C, enclosed in this .ARC.   <<<<
;
;  REFERENCES:
;
;   _chips is made up of two PROC's, cpu_type and ndp_type.
;
;    cpu_type is based on uncopyrighted, published logic by
;     Clif (that's the way he spells it) Purkiser of Intel -
;     Santa Clara.
;
;    ndp_type is adopted from Ted Forgeron's article in PC
;     Tech Journal, Aug '87 p43.
;
;   In the event of subsequent republication of this function,
;    please carry forward reference to these two gentlemen as
;    original authors.
;
;    Copr. 1987   Pat Shea - Psi! (that Copr. is on there cuz my
;                    lawyer sez I should, but feel
;                    free to hack away!!!  pats.)
;
;    Update:  1/1/88 - changed this code slightly so that it is
;             compilable using MASM 5.0, and the test.c
;             file using MSC 5.0. <Albert Stein>
.MODEL SMALL
.CODE
    PUBLIC _chips
_chips     PROC
control dw   0       ; control word needed for the NDP test
    push  BP       ; save where Ur at
    mov  BP,SP     ;  going in.....
    push  DI
    push  SI
    push  CX       ; not really needed for MSC but kinda
               ;  nice to do cuz someone else might
               ;  want to use the function and we do
               ;  use CX later on
    call  cpu_type    ; find out what kinda CPU you got and
               ;  and save it in DX for future reference
    call  ndp_type    ; check for math coprocessor (NDP) type
               ;  and hold that result in AX
    add  AX,DX     ; add the two results together and hold
               ;  'em in AX for Ur return to the caller
    pop  CX       ; put things back the way that you
    pop  SI       ;  found 'em when you started this
    pop  DI       ;  little drill off.....
    pop  BP
               ; AND
    ret          ; go back to where you came from....
               ;  ( ===> the calling program )
               ;  with Ur results sittin' in AX !!
_chips     endp
cpu_type    PROC
    pushf         ; pump Ur flags register onto the stack
    xor  DX,DX     ; blow out Ur DX and AX to start off
    xor  AX,AX     ;  with a clean slate
    push  AX       ; put AX on the stack
    popf         ; bring it back in Ur flags
    pushf         ; try to set bits 12 thru 15 to a zero
    pop  AX       ; get back Ur flags word in AX
    and  AX, 0f000h   ; if bits 12 thru 15 are set then you got
    cmp  AX, 0f000h   ;  an Intel 8018x or a 808x or maybe even
    jz   dig      ;  a NEC V20/V30 ??? - gotta look more...
; OTHERWISE....
;  Here's the BIG one.... 'tells the difference between an 80286 and
;  an 80386 !!
    mov  AX, 07000h   ; try to set FLAG bits 12 thru 14
               ;  - NT, IOPL
    push  AX       ; put it onto the stack
    popf         ;  and try to pump 07000H into Ur flags
    pushf         ; push Ur flags, again
    pop  AX       ;  and bring back AX for a compare
    and  AX,07000h   ; if Ur bits 12 thru 14 are set
    jnz  got386     ;  then Ur workin' with an 80386
    mov  DX, 0280    ; save 280 in DX cuz it's an 80286
    jmp  SHORT CPUbye  ;  and bail out
got386: mov  DX, 0380    ; save 380 in DX cuz it's an Intel 80386
    jmp  SHORT CPUbye  ;  and bail out
; here's we try to figger out whether it's an 80188/80186, an 8088/8086
;  or an NEC V20/V30 - 'couple of slick tricks from Clif Purkiser.....
dig:  mov  AX, 0ffffh   ; load up AX
    mov  CL, 33     ; HERE's the FIRST TRICK.... this will
               ;  shift everything 33 times if it's
               ;  8088/8086, or once for a 80188/80186!
    shl  AX, CL     ; on a shift of 33, all bits get zeroed
    jz   digmor     ;  out so if anything is left ON it's
               ;  gotta be an 80188/80186
    mov  DX,0180    ; save 180 in DX cuz it's an 80188/80186
    jmp  SHORT CPUbye  ;  and bail out
digmor: xor  AL,AL     ; clean out AL to set ZF
    mov  AL,40h     ; ANOTHER TRICK.... mul on an NEC duz NOT
    mul  AL       ;  effect the zero flag BUT on an Intel
    jz   gotNEC     ;  8088/8086, the zero flag gets thrown
    mov  DX,0080    ; 80 into DX cuz it's an Intel 8088/8086
    jmp  SHORT CPUbye  ;  and bail out
gotNEC: mov  DX,0200    ; it's an NEC V20/V30 so save 200 in DX
CPUbye: popf         ; putchur flags back to where they were
    ret          ;  and go back to where you came from
               ;  (i.e., ===> _chips) with the CPU type
               ;  tucked away in DX for future reference
cpu_type    endp
; Check for an NDP.
;
; >>>>NOTE: If you are using an MASM version < 5.0, don't forget to
; use the /R option or you will bomb cuz of the coprocessor instruc-
; tions. /R is not needed for version 5.0.<<<<<<<<<<<<<<<<<<<<<<<<<
ndp_type    PROC
do_we: fninit             ; try to initialize the NDP
    mov  byte ptr control+1,0   ; clear memory byte
    fnstcw control         ; put control word in memory
    mov  AH,byte ptr control+1  ; iff AH is 03h, you got
    cmp  AH,03h          ;  an NDP on board !!
    je   chk_87          ; found somethin', keep goin'
    xor  AX,AX          ; clean out AX to show a zero
    jmp  SHORT NDPbye       ;  return (i.e., no NDP)
; 'got an 8087 ??
chk_87: and  control,NOT 0080h    ; turn ON interrupts (IEM = 0)
    fldcw control         ; load control word
    fdisi              ; turn OFF interrupts (IEM = 1)
    fstcw control         ; store control word
    test  control,0080h      ; iff IEM=1, 8087
    jz   chk287          ; 'guess not! March on....
    mov  AX,0001         ; set up for a 1 return to
    jmp  SHORT NDPbye       ;  show an 8087 is on board
; if not.... would you believe an 80287 maybe ??
chk287: finit         ; set default infinity mode
    fld1         ; make infinity
    fldz         ;  by dividing
    fdiv         ;  1 by zero !!
    fld  st       ; now make a
    fchs         ;  negative infinity
    fcompp        ; compare Ur two infinities
    fstsw control    ; iff, for 8087 or 80287
    fwait         ; sit tight 'til status word is put away
    mov  AX,control   ; getchur control word
    sahf         ; putchur AH into flags
    jnz  got387     ; NO GOOD.... march on !!
    mov  AX,0002    ; gotta be a 80287 cuz we already tested
    jmp  SHORT NDPbye  ;  for an 8087
; We KNOW that there is an NDP on board otherwise we would have bailed
; out after 'do_we'. It isn't an 8087 or an 80287 or we wouldn't have
; gotten this far. It's gotta be an 80387 !!
got387: mov  AX,0003    ; call it an 80387 and return 3
NDPbye: ret          ; and go back where you came from
               ;  (i.e., ===> _chips) carrying the NDP
               ;  type in Ur AX register
ndp_type    endp
_text  ends
    end
 

小编工资已与此挂钩!一一分钱!求打赏↓ ↓ ↓

如果你喜欢本文章,请赐赏:

已赐赏的人
最新评论(共0条)评论一句