📄 win95.asm
字号:
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 + -