⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 win95.asm

📁 部分常用系统的引导程序
💻 ASM
📖 第 1 页 / 共 3 页
字号:
                CMP     DI,BX
                JB      CheckEntry                  ; Jump if below

        ; are there any more sectors in this cluster???

		DEC	SI
                JNZ     GetRootSector           ; yeap, read more

                POP     AX              ; restore cluster number
                POP     DX

        ; Get FAT value... "GetFAT32Value" will compare the value with
        ; -8, and the JB below continues if below... that is, non-EOF/BAD
        ; the "previous cluster" value is taken from DX:AX (as restored
        ; above with POP).

                CALL    GetFAT32Value
                JB      GetRootCluster

        ; if not end of root... go to GetRootCluster..

EndOfRoot:                                      ; EOF/BAD cluster...
                ADD     SP,4                    ; clean up stack...
                JMP     ShowErrMsg1             ; and print error message
FoundOS:
                ADD     SP,4                    ; clean up...


        ; Now... DI should point just above the IO.SYS name...

        ; SI would be set to DirEntry[14H] - starting cluster (HI)
        ; DI would be set to DirEntry[1AH] - starting cluster (LO)

                MOV     SI,[DI+09H]
		MOV	DI,[DI+0FH]

        ; copy FAT32 starting cluster upper 16-bits to AX

                MOV     AX,SI

		CLI				; Disable interrupts

        ; shift cluster high into upper half of EAX and store lower half
        ; from DI into AX

                SHL     EAX,10H
                MOV     AX,DI

        ; cluster out of range??

                CMP     EAX,2                   ; clusters start with 2
                JB      InvalidCluster

                CMP     EAX,0FFFFFF8H           ; cluster 0FFFFFF8 is EOF
                JAE     InvalidCluster

                DEC     EAX                     ; make it 0-based...
                DEC     EAX

        ; Multiply cluster number with "sectors per cluster"

                MOVZX   ECX,BYTE PTR SS:[BP+0DH]
                MUL     ECX

        ; Add the "start of data area" value that was saved back there...

                ADD     EAX,SS:[BP-4]

        ; And for the N'th time, make DX:AX same as EAX - sector number.

                SHLD    EDX,EAX,10H

                STI                             ; aha...

                MOV     BX,0700H                ; IO.SYS loads here!

                PUSH    BX
                MOV     CX,4                    ; load 4 IO.SYS sectors
                CALL    ReadSectorX             ; 2K is minimum FAT32 cluster
                POP     BX                      ; size anyway...

                JC      ShowErrMsg2             ; error...???


        ; COMMENT:
        ;
        ; Now, there is enough code here... to read the entire IO.SYS
        ; file into memory. This code has code to go through the FAT,
        ; there is code to read cluster... bla bla. And still only 2K
        ; of IO.SYS is read. If the entire file was read... IO.SYS would
        ; not have to do this... well well.

        ; Is there a Mark Zibikowski in the room?

                CMP     WORD PTR [BX],'ZM'              ; EXE signature...
                JNE     InvalidCluster

        ; Is there a Barabara Jones in the room?

                CMP     WORD PTR DS:[0200H][BX],'JB'    ; IO.SYS signature?
                JE      ExecutIOSYS

        ; The above shit appear in the IO.SYS file at offsets 0 and 200h
        ; The MZ is the usual EXE signature while the "BJ" is unknown to
        ; me. Maybe they chose it because it translates to harmless code:
        ;
        ;   INC DX - DEC DX, pretty dull if you ask me ;)
        ;
InvalidCluster:
                MOV     SI,OFFSET ErrMsg3 + 7C00H
                JMP     PrintMessage
ExecutIOSYS:
                DB      0EAH            ; Jump to IO.SYS at 0070:0200
                DW      0200H, 0070H

;==========================================================================
;                              GET FAT32 VALUE
;==========================================================================

GetFAT32Value   PROC    NEAR

                ADD     AX,AX                   ; Multiply DX:AX by 4,
                ADC     DX,DX
                ADD     AX,AX                   ; convert DX:AX from FAT32
                ADC     DX,DX                   ; index value to offset

        ; DX:AX is passed on as the FAT offset to lookup...

                CALL    GetFAT32Sector          ; read FAT sector

        ; the correct sector is returned... with DI as index...??
        ; At least that's what the MOV below assumes...

                CLI

                MOV     EAX,ES:[BX+DI]          ; EAX = cluster value

        ; mask of top 4 bits of because Microsoft say it's reserved.

                AND     EAX,0FFFFFFFH           

        ; Make DX:AX the cluster number too...

                SHLD    EDX,EAX,16              ; EAX[HI] into EDX[LO]

        ; Check for EOF/BAD

                CMP     EAX,0FFFFFF8H           ; Is it the EOF marker?

                STI                             ; return with ZF=1 if the
                                                ; last cluster was read??
                RET

GetFAT32Value   ENDP

;==========================================================================
;                         GET FAT32 SECTOR
;==========================================================================

; On entry DX:AX is the FAT offset in bytes...

GetFAT32Sector  PROC    NEAR

        ; When this is called 0070:0200 seems to be the buffer in ES:BX
        ; but, the code below uses the DI value set down under here...

                MOV     DI,7E00H

		CLI				; Disable interrupts

        ; make EAX the sector number again... move DX into top of EAX...

                SHL     EAX,16
                SHRD    EAX,EDX,16

        ; move bytes per sector into ECX

                MOVZX   ECX,WORD PTR SS:[BP+0BH]

        ; divide EDX:EAX by BPS... EAX = sector, EDX = offset in sector...

                XOR     EDX,EDX
                DIV     ECX

        ; Check FAT sector number agains... saved value on stack...
        ; This one is initially -1 (also known as 0FFFFFFFFH)

                CMP     EAX,SS:[BP-8]   
                JE      LOC_30

        ; If sector is <> from -1, save this sector at 0000:7BF8

                MOV     SS:[BP-8],EAX   

        ; add hidden sectors... 

                ADD     EAX,SS:[BP+1CH]

        ; add reserved sectors too... 

                MOVZX   ECX,WORD PTR SS:[BP+0EH]
                ADD     EAX,ECX

        ; get FAT32 flags into EBX

                MOVZX   EBX,WORD PTR SS:[BP+28H]

        ; keep "Active FAT" bits 0-3

                AND     BX,0FH

        ; If zero, we're at the correct FAT

                JZ      CorrectFAT

        ; compare active FAT with number of FATs...

                CMP     BL,SS:[BP+10H]
                JAE     ShowErrMsg1     ; oops... invalid active FAT
                
                PUSH    DX              ; save DX for a while...

        ; save FAT sector in ECX

                MOV     ECX,EAX

        ; Put sectors per fat in EAX

                MOV     EAX,SS:[BP+24H]

        ; Multiply active FAT number with sectors per FAT

                MUL     EBX

        ; Add to first FAT sector number we already had...

                ADD     EAX,ECX

        ; NOW, EAX contains the correct FAT sector number.

                POP     DX
CorrectFAT:
                PUSH    DX

        ; And for the N'th time, make DX:AX same as EAX - sector number.

                SHLD    EDX,EAX,16

		STI				; Enable interrupts

                MOV     BX,DI                   ; read FAT sector into
                                                ; 0000:7E00

        ; They sucker who wrote this could have saved 1 byte by
        ; saying XOR CX,CX instead of MOV CX,1 and called ReadSector
        ; instead of ReadSectorX, because there is an INC CX at
        ; ReadSector... haha...

                MOV     CX,1                    ; 1 sector
                CALL    ReadSectorX

                POP     DX

                JC      ShowErrMsg2
LOC_30:
		STI				; Enable interrupts
                MOV     BX,DX
                RET

GetFAT32Sector  ENDP

        ; Properly align the sector's boot signature at the end of
        ; the 3rd boot sect0r.

                ORG     512 * 3 - 2

                DW      0AA55H                  ; 3rd Boot Signature

CODE            ENDS

                END

; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;
;  CONCLUSION - THE END - HASTA LA VISTA - SLUTT - DET VAR ALT FOR I DAG.
;
;  OK, Folks. that was quite a bit of work. It got pretty simple after some
;  hours. 
;
;  I would like to thank the following people...
;
; * V Communications for Sourcer.
; * Ralf Brown for the Interrupt List.
; * Uriah Heep, The Who and Blind Guardian, for providing music.
;
; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -