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

📄 gfat16_p.asm

📁 操作系统实验教程核心技术与编程实例书中地例子代码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
       MOV AL,ES:[SI+3]        ; driver_no  4=D
       DEC AL
       MOVZX AX,AL
       XOR DX,DX
       MOV CX,512
       MUL CX                  ;ax=offset of Logical boot sector 
       MOV BX,OFFSET DOSBOOTA
       ADD BX,AX
                               ; FS:BX logical boot sector addr
       MOV AX,FS:[BX+0BH]      ; bytes per sector
       PUSH AX                 ; bytes per sector into statck ebp-28
       MOVZX EAX,AX
       MOV CL,FS:[BX+0DH]      ; sectors per cluster
       MOVZX ECX,CL
       XOR EDX,EDX
       MUL CX                  ; Eax=bytes per cluster
       MOV ECX,EAX             ; ECX==bytes per cluster
       MOV AX,[EBP-20]
       MOVZX EAX,AX
       XOR EDX,EDX
       DIV ECX                 
       CMP EDX,0
       JLE FREAD1
       INC EAX                 ; EAX=clusters to read
FREAD1:       
       MOV ECX,DWORD PTR ES:[SI+27]
       PUSH ECX                ; begin cluster_no into stack EBP-32
       INC EAX       

       MOV CL,ES:[SI+2]        ; property of dir
       ADD CL,10H
       CMP CL,10H
       JNE FREAD1_2
       MOV EAX,0FFFFH          ;=subs directory :end cluster_NO=0FFFFH
FREAD1_2:
       PUSH EAX                ; EAX=cluster_nos to read+1 into stack EBP-36
       ;;
       MOV CL,FS:[BX+0DH]
       MOVZX CX,CL
       PUSH CX                  ;setctors per cluster into stack EBP -38(64)
       MOV AX,FS:[BX+11H]      ; root directory items(512)
       MOVZX EAX,AX
       MOV CX,32
       MOVZX ECX,CX
       XOR EDX,EDX
       MUL ECX                 ;eax=bytes of root directory
       MOV CX,[EBP-28]
       XOR EDX,EDX
       MOVZX ECX,CX
       DIV ECX                 ;eax=sectors of root directory

       PUSH EAX
       MOV AL,FS:[BX+10H]       ;FAT_COUNT
       MOVZX EAX,AL
       MOV CX,FS:[BX+16H]       ;sectors per FAT
       MOVZX ECX,CX
       XOR EDX,EDX
       MUL ECX                  ;eax=sectors of 2 FATS
       POP ECX
       ADD EAX,ECX             
       INC EAX                  ;first logical sector_no of file area
       PUSH EAX                 ;first logical sector_no of file area ebp-42
       MOV  AX,1
       PUSH AX                  ;current sector_no per cluster  EBP-44
       PUSH EAX      ;                                          EBP-48
       MOV DWORD PTR [EBP-26],1   ;begin cluster             ;|,1
       ;;;loop read
;jmp fread_end
FREAD2:           ;<-----------------------------------cluster loop             
       MOV EAX,DWORD PTR [EBP-26] ;begin cluster       (1)   ;|
       CMP EAX,DWORD PTR [EBP-36] ;clusters to read +1   (2)
       JG  FREAD_END

       INC DWORD PTR [EBP-26]     ;
       MOV EAX,DWORD PTR [EBP-32] ;begin cluster_no  (3c29)  ;|
       DEC EAX
       DEC EAX
       MOV CX,WORD PTR [EBP-38]   ;40h
       MOVZX ECX,CX
       XOR EDX,EDX
       MUL ECX                    ;eax=0F0980h
       ADD EAX,DWORD PTR [EBP-42] ;first logical sector_no (0f0ba1h)
       MOV DWORD PTR [EBP-48],EAX
       MOV WORD PTR [EBP-44],1
FREAD22:          ;<------------------------------sectors per cluster loop
       MOV CX,WORD PTR WORD PTR [EBP-44]                      ;|
       CMP CX,WORD PTR [EBP-38]
       JA  FREAD4
       INC WORD PTR WORD PTR [EBP-44]                      
       PUSH DS
       PUSH BX    ;offset of logical boot sector
       MOV  CX,FS
       MOV  DS,CX
       MOV  DX,BX
       MOV  EAX,DWORD PTR [EBP-48]
       INC  DWORD PTR [EBP-48]
       CALL READ_ONE_SECTOR   ;into V_TOS_DATA_SEL:ttsector
       POP  BX
       POP  DS
       ;;;;;;;;;;;;;;;;;;;;;;;;move ttsector -->buf
       MOV EAX,DWORD PTR ES:[SI+36]
       MOV EDI,EAX            ;here simply: file pointer=user buf pointer
       MOV CX,[EBP-28]        ;bytes per sector
       MOVZX ECX,CX
       ADD EAX,ECX
       ;;
       MOV CL,ES:[SI+2]        ; property of dir
       AND CL,10H
       CMP CL,10H
       JE FREAD3
       ;;
       CMP EAX,DWORD PTR ES:[SI+19]
       JLE FREAD3
       MOV EAX,DWORD PTR ES:[SI+19]   ;is not directory 
FREAD3:
       MOV DWORD PTR ES:[SI+36],EAX ;save current file pointer
       PUSH SI
       PUSH DS
       PUSH ES
       MOV SI,OFFSET TTSECTOR
       MOV AX,FS
       MOV DS,AX
       MOV AX,GS
       MOV ES,AX
       REP MOVSB
       POP ES
       POP DS
       POP SI

       ;;;;;; file_end check     
       ;; directory file continue
       MOV CL,ES:[SI+2]        ; property of dir
       AND CL,10H
       CMP CL,10H
       JE FREAD22              ; next sector in one cluster
       ;;
       MOV EAX,DWORD PTR ES:[SI+36]      ; current pointer
       CMP EAX,DWORD PTR ES:[SI+19]      ; file length
       JAE FREAD_END
       JMP FREAD22
FREAD4:
       ;;    find next cluster_no in FAT
       PUSH DS
       PUSH BX
       PUSH DX
       MOV AX,FS
       MOV DS,AX
       MOV DX,BX
       MOV EAX,DWORD PTR [EBP-32] ;current cluster_no 
       CALL NEXT_CLUSTER
       POP DX
       POP BX
       POP DS
       CMP EAX,0FFF8H                 ;EAX=0FFF8H :last cluster
       JAE  FREAD_END
       ;;;; eax=next cluster_no  into EBP-32
       MOV DWORD PTR [EBP-32],EAX
       JMP FREAD2

FREAD_END:
       ;;;;;;;;;;;;;;;;;;;;;;;;;;;
       SUB EBP,18
       MOV ESP,EBP
       POP FS
       POP BX
       POP ES
       POP DX
       POP DS
       POP DI
       POP SI
       POP EBP
       RET
FREAD  ENDP

FREAD_DAT   PROC FAR
            ;in: directory in dat structure
            ; setup file handle
            MOV AX,V_TOS_DATA_SEL 
            MOV DS,AX
            MOV DX,OFFSET DAT
            ADD DX,80
            CALL GET_HANDLE     ;out ax=handle
            CMP AX,65535
            JE FIND_DIR_END_ERROR    ;no sft or opt free item
            ; setup file handle
            ;;;read the file
            PUSH DS
            PUSH ES
            PUSH AX                  ;handle
            MOV AX,V_TOS_DATA_SEL 
            MOV ES,AX
            MOV BX,OFFSET OPT
            POP AX
            PUSH AX
            ADD BX,AX
            MOV DX,ES:[BX]
            MOVZX EDX,DX
            MOV DWORD PTR ES:TTDD1,EDX      ;subs in sft -->ttdd1 =1:CHIS
            MOV BX,OFFSET OPT
            MOV DX,V_FILE_BUF_SEL
            MOV DS,DX
            MOV DX,0        ;ds:dx read buffer = 2M -128K
            MOV CX,0FFFFH   ;read 32K per time
            POP AX
            CALL FREAD       ;ok
            POP ES
            POP DS
            ;;;read the file
            ret
FREAD_DAT   ENDP

DO_DOS21H4E PROC FAR
            ;in : ds:dx file_name asciiz string cx=0 normal file
            ;out ax=0 ok information-->file_info ax<>0:error
            ;"D:\CHIS\TTT\MODE_BIG.TXT"-----file_name
            PUSH DX
            
            
            ;;;;;;;;;;;; move file_name string to str1
            MOV BX,OFFSET STR1
            PUSH BX
            PUSH DS
            PUSH DX
            PUSH DS
            CALL STRCPY
            ;;;;;;;;;;;; move file_name string to str1

            POP DX
            PUSH DX
            MOV BX,DX
            MOV CL,DS:[BX]    ;driver for example: C
            CMP CL,61H
            JL  DOS21H4E_1
            SUB CL,20H         ;change to lower
DOS21H4E_1:
            MOV DS:TTDB,CL
            CMP CL,'C'
            JE  DOS21H4E_2     ;root directory (c:\)

            ;;;;;;;;;;;;;;;; Read DOS logical part table sector in EXTpart
            ;; for one hard disk
            SUB CL,43H         ;cx=2 driver E  loop_count
            MOV DS:TTDB1,CL    ;TTBD1=loop_count
            MOV CL,1
            MOV DS:TTDB,CL     ;TTDB=loop begin
DOS21H4E_10:
            MOV CL,DS:TTDB
            CMP CL,DS:TTDB1
            JA  DOS21H4E_22    ;end
            ;;;;;;;;;;;;;;;; read Part table in EXTpart use INT13H 02
            MOV AX,V_TOS_DATA_SEL
            MOV DS,AX
            MOV ES,AX
            MOV CL,1
            CMP CL,DS:TTDB
            JNE DOS21H4E_11
            MOV BX,OFFSET PRIBOOT
            JMP DOS21H4E_12
DOS21H4E_11:
            MOV BX,OFFSET WORKBOOT
DOS21H4E_12:
            ADD BX,1CFH            ;part 2
            MOV CH,DS:[BX+2]       ;cylinder
            MOV DS:TTDBX,CH
            MOV CL,DS:[BX+1]       ;sector
            MOV DS:[TTDBX+1],CL
            MOV DH,DS:[BX]         ;head
            MOV DS:[TTDB+2],DH
            MOV BX,OFFSET WORKBOOT
            MOV AH,2
            MOV AL,1
            MOV DL,80H     ;driver: hard disk 1
            INT 83H        ;=bios 13h
            INC  DS:TTDB
            LOOP DOS21H4E_10
            ;;;;;;;;;;;;;;;; Read DOS logical part table sector in EXTpart

            ;;;;;;;;;;;;;;;; Read EXTDOSboot sector
DOS21H4E_22: ;;;;;;;;;;;;;;;  is not "C:\...."
            MOV BX,OFFSET WORKBOOT  ;part 1 begin position 446
            JMP DOS21H4E_29
DOS21H4E_2: ;;;;;;;;;;;;;;;   is     "C:\...."
            MOV AX,V_TOS_DATA_SEL
            MOV DS,AX
            MOV ES,AX
            MOV BX,OFFSET PRIBOOT
            MOV AL,0
            MOVZX EAX,AL
            MOV DS:HIDDEN_SECTOR,EAX
DOS21H4E_29:
            ADD BX,447
            MOV CH,DS:[BX+2]       ;cylinder
            MOV CL,DS:[BX+1]       ;sector
            MOV DH,DS:[BX]         ;head
            MOV BX,OFFSET WORKBOOT
            MOV AH,2
            MOV AL,1
            MOV DL,80H     ;driver: hard disk 1
            INT 83H        ;=bios 13h

            ;;;;;;;;;;;;;;;; Read EXTDOSboot sector----->END
            ; now DOSboot or EXTdosboot -->workboot

            ;;; logical_boot_sector --> DOSBOOTA
            PUSH EAX
            PUSH EBX
            PUSH ECX
            PUSH EDX
            PUSH SI
            PUSH DI
            PUSH DS
            PUSH ES

            MOV AX,V_TOS_DATA_SEL
            MOV DS,AX
            MOV ES,AX
            MOV DI,OFFSET DOSBOOTA
            XOR DX,DX
            MOV AX,512
            MOV CL,DS:STR1     ;file_name in str1 AL=driver_C(D)
            SUB CL,40H         ;al=driver_no   (1=A 3=C 4=D)
            DEC CL
            MOV CH,0
            MUL CX             ;AX=OFFSET from DOSBOOTA
            ADD DI,AX          ;to ADDRESS
            MOV SI,OFFSET WORKBOOT
            MOV CX,256
            REP MOVSW
            POP ES
            POP DS
            POP DI
            POP SI
            POP EDX
            POP ECX
            POP EBX
            POP EAX
            ;;; logical_boot_sector --> DOSBOOTA

;KKKKKKKKKKKKKKKK Count hidden sectors before the logcal (D)
            CMP DS:TTDB,'C'
            JE  DOS21H4E_30
            PUSH EAX
            PUSH EBX
            PUSH ECX
            PUSH EDX
            ;MOV DS:TTDBX,CH ;cylinder
            ;MOV DS:TTDBX+1,CL ;sector
            ;MOV DS:TTDBX+2,DH ;head
            MOV CH,DS:TTDBX
            MOV CL,DS:[TTDBX+1]
            MOV DH,DS:[TTDBX+2]

            MOV AH,CL
            MOV AL,CH
            SHR AH,6                 ;ax=cylinder--ok
            AND CL,3FH               ;begin sector--ok
            MOV CH,DH                ;begin head---ok
            PUSH CX

            MOVZX EAX,AX
            XOR EDX,EDX
            MOV CX,DS:[BX+18H]       ;sectors per head
            MOVZX ECX,CX
            MUL ECX
            MOV CX,DS:[BX+1AH]       ;heads per cylinder
            MOVZX ECX,CX
            XOR EDX,EDX
            MUL ECX                  ;eax=sectors of cylinders

            POP CX
            PUSH EAX
            PUSH CX
            SHR CX,8                 ;head_no
            MOVZX ECX,CX
            MOV AX,DS:[BX+18H]       ;sectors per head
            MOVZX EAX,AX
            MUL ECX

            POP DX
            POP EAX
            ADD EAX,ECX
            DEC DL
            MOVZX EDX,DL
            ADD EAX,EDX
            MOV DS:HIDDEN_SECTOR,EAX
            POP EDX
            POP ECX
            POP EBX
            POP EAX
;KKKKKKKKKKKKKKKK
DOS21H4E_30:
            ;;;;;;;;;;;begin to D:\CHIS\TTT\XXXX.TXT
            ;;;;;;;;;;; info in WORKBOOT
            MOV AL,3
            MOV DS:TTDB,AL       ;pointer to \
            MOV AL,'\'
            MOV DS:STR3,AL       

            ;;count length of str1
            MOV DI,OFFSET STR1
            PUSH ES
            MOV BX,DS
            MOV ES,BX
            PUSH DI
            MOV AL,0
            MOV CX,80
            CLD
            REPNZ SCASB
            MOV BX,DI
            POP DI
            SUB BX,DI
            SUB BX,3              ;cut off "D:\
            MOV DS:STR3+8,BL     ;next time search length in str1
            POP ES
            ;;count length of str1
DOS21H4E_3:                      ;outer loop begin_position
            ;;;;;;;;;;;;;;;;;;;;; look for next_\_begin_position

            MOV BL,DS:TTDB
            MOVZX BX,BL
            MOV DI,OFFSET STR1

            ADD  DI,BX           
            MOV  CL,DS:STR3+8
            MOVZX CX,CL          ;loop+count
            MOV DX,DS
            MOV ES,DX
            CMP CX,0
            JE  DOS21H4E_ERROR
DOS21H4E_31: 
            MOV AL,'\'
            CLD
            SCASB
            LOOPNZ DOS21H4E_31
            JE DOS21H4E_319       ;is not last one

            ;NO '\' is last: MODE_X.TXT ---> 11 chars:MODE_X  TXT-->str2
            MOV AX,V_TOS_DATA_SEL
            MOV DS,AX
            MOV ES,AX
            MOV SI,OFFSET STR1
            MOV AL,DS:TTDB
            MOVZX AX,AL
            ADD SI,AX              ;si-->M
            MOV DI,OFFSET STR2
            MOV CX,8
DOS21H4E_310:
            CLD
            MOV AL,DS:[SI]        ; str1
            CMP AL,0
            JE DOS21H4E_311
            CMP AL,'.'
            JE DOS21H4E_312
            CMP CX,1
            JLE

⌨️ 快捷键说明

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