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

📄 gfat16_p.asm

📁 操作系统实验教程核心技术与编程实例书中地例子代码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
           POP EDX
           POP ECX
           POP EBX
           RET
DISK_FREE  ENDP
            
FILE_INIT   PROC FAR
            ; out AL=1 is not FAT16
            PUSH EAX
            PUSH BX
            PUSH CX
            PUSH DX
            PUSH DS
            PUSH ES
;jmp FILE_INIT_END
            ; sft init
            MOV AX,V_SFT_SEL
            MOV ES,AX
            MOV DI,0
            MOV CX,16384
            MOV EAX,0
            REP STOSD
            ;;;;;;;;;;;;;;;;;;;;; read priboot use INT13H 02
            MOV AX,V_TOS_DATA_SEL
            MOV DS,AX
            MOV ES,AX
            MOV BX,OFFSET PRIBOOT
            MOV AH,2
            MOV AL,1
            MOV CH,0       ;cylinder
            MOV CL,1       ;sector
            MOV DH,0       ;head
            MOV DL,80H     ;driver: hard disk 1
            INT 83H        ;=bios 13h
            ;;;;;;;;;;;;;;;;;;;;;; read DOSboot use INT13H 02
            MOV AX,V_TOS_DATA_SEL
            MOV DS,AX
            MOV BX,OFFSET PRIBOOT
            ADD BX,447             ;part 1 begin position 446
            MOV CH,DS:[BX+2]       ;cylinder
            MOV CL,DS:[BX+1]       ;sector
            MOV DH,DS:[BX]         ;head
            MOV BX,OFFSET DOSBOOT
            MOV AH,2
            MOV AL,1
            MOV DL,80H     ;driver: hard disk 1
            INT 83H        ;=bios 13h
            ;;;;;;;;;;;;;;;;;;;;;; is FAT16 ?
            MOV BX,OFFSET DOSBOOT
            MOV AL,DS:[BX+36H]
            CMP AL,'F'
            JNE DO_DIR_END
            MOV AL,DS:[BX+37H]
            CMP AL,'A'
            JNE DO_DIR_END
            MOV AL,DS:[BX+38H]
            CMP AL,'T'
            JNE DO_DIR_END
            MOV AL,DS:[BX+39H]
            CMP AL,'1'
            JNE DO_DIR_END
            MOV AL,DS:[BX+3AH]
            CMP AL,'6'
            JNE FILE_INIT_ENDE

            ;;;;;;;;;;;;;;;;;;;  Next is FAT16
            ;;;;;;;;;;;;;;;;;;; Set up SYS_curret_dir as:c:\ etc.
            MOV AL,'C'
            MOV AH,':'
            MOV WORD PTR DS:[SYS_CURRENT_DIR],AX ; "C:"
            MOV AL,'\'
            MOV AH,0
            MOV WORD PTR DS:[SYS_CURRENT_DIR+2],AX ; "\",0
            MOV AX,70H
            MOV WORD PTR DS:[SYS_CURRENT_DIR+67],AX ; driver
            MOV BX,OFFSET DOSBOOT
            ADD BX,0BH                          ;BPB offset
            MOV AX,DS
            MOV WORD PTR DS:[SYS_CURRENT_DIR+69],AX ;ds
            MOV WORD PTR DS:[SYS_CURRENT_DIR+71],BX ;offset
            MOV AL,2
            MOV DS:[SYS_CURRENT_DIR+80],AL ; offset for \


            JMP FILE_INIT_END
FILE_INIT_ENDE:
            MOV AL,1
            JMP FILE_INIT_ENDOK
FILE_INIT_END:
            MOV AL,0
FILE_INIT_ENDOK:
            POP ES
            POP DS
            POP DX
            POP CX
            POP BX
            POP EAX
            RET
FILE_INIT   ENDP

GET_HANDLE  PROC FAR
            ;in: ds:dx address of directory item
            ;out : ax=handle
            PUSH EBX
            PUSH ECX
            PUSH EDX
            PUSH DS
            PUSH ES
            PUSH SI
            PUSH DI
            PUSH DX
            ;;;;;;;;

            ; find free item in sft
            MOV SI,DX
            MOV AX,V_SFT_SEL
            MOV ES,AX
            MOV DI,40
            MOV CX,1637        ;1638 items in sft
            MOV AL,0
GET_HANDLE_1: 
            CMP ES:[DI],AL
            JE GET_HANDLE_2  
            ADD DI,40
            LOOP GET_HANDLE_1
            JMP GET_HANDLE_ERROR

GET_HANDLE_2:
            ; FOUND a free item
            MOV AX,DI
            XOR DX,DX
            MOV CX,40
            DIV CX          ;ax=sft_no
            PUSH AX
            ; find free item in sft

            ; ;;;;;;;;;;;;;;; fill sft
            ;
            ; DI=sft_start_addr
            MOV AL,1
            MOV ES:[DI],AL   ; use the item
            MOV AL,0
            MOV ES:[DI+1],AL ; only read
            MOV AL,DS:[SI+0BH]
            MOV ES:[DI+2],AL ; file property
            PUSH DS
            MOV AX,V_TOS_DATA_SEL
            MOV DS,AX
            MOV AL,DS:STR1
            SUB AL,40H
            POP DS
            MOV ES:[DI+3],AL ; Driver_NO
            PUSH SI
            PUSH DI
            ADD DI,4
            MOV CX,11
            REP MOVSB     ;move file name and extended name to sft
            POP DI
            POP SI
            MOV EAX,DWORD PTR DS:[SI+1CH]
            MOV DWORD PTR ES:[DI+19],EAX  ;file length
            MOV AX,WORD PTR DS:[SI+1AH]   ;begin cluster_no
            MOVZX EAX,AX
            MOV DWORD PTR ES:[DI+27],EAX  ;begin cluster_no
            MOV AX,WORD PTR DS:[SI+18H] ;date
            MOV WORD PTR ES:[DI+23],AX  ;date
            MOV AX,WORD PTR DS:[SI+16H] ;time
            MOV WORD PTR ES:[DI+25],AX  ;time
            MOV EAX,0
            MOV DWORD PTR ES:[DI+36],EAX  ;POINTER

            ; find free item in opt
            MOV AX,V_TOS_DATA_SEL 
            MOV ES,AX
            MOV DI,OFFSET OPT
            MOV CX,512
            MOV AX,0
GET_HANDLE_3: 
            SCASW
            JE GET_HANDLE_4
            LOOP GET_HANDLE_3
            JMP GET_HANDLE_ERROR
GET_HANDLE_4:
            ; find free item in OPT
            POP AX        ;ax=sft_no
            SUB DI,2
            MOV WORD PTR ES:[DI],AX
            MOV AX,DI
            MOV DI,OFFSET OPT
            SUB AX,DI
            JMP GET_HANDLE_RET
GET_HANDLE_ERROR:
            MOV AX,65535

GET_HANDLE_RET:
            POP DX
            POP DI
            POP SI
            POP ES
            POP DS
            POP EDX
            POP ECX
            POP EBX
            RET
GET_HANDLE  ENDP

READ_ONE_SECTOR PROC FAR
            ; in: DS:DX=dosboot or extdosboot EAX=logic sector_no
            ;;;;;;;;;;;;;;;;;;;;;; read ONE sector to DS:TTSECOR
            PUSH AX
            PUSH BX
            PUSH CX
            PUSH DX
            PUSH ES
            CALL LSECTOR_NO_ADDR  ; in: DS:DOSBOOT  OR EXTDOSBOOT EAX=logic sector_no
                                  ; out ch:cylinder,cl:sector,dh:head
            ;MOV CH,0       ;cylinder
            ;MOV CL,10      ;sector
            ;MOV DH,9       ;head
            MOV AX,DS
            MOV ES,AX
            MOV BX,OFFSET TTSECTOR
            MOV AH,2
            MOV AL,1
            MOV DL,80H     ;driver: hard disk 1
            INT 83H        ;=bios 13h
            ;;;;;;;;;;;;;;;;;;;;; display dir in one sector
            POP ES
            POP DX
            POP CX
            POP BX
            POP AX
            RET
READ_ONE_SECTOR ENDP

NEXT_CLUSTER PROC FAR
             PUSH SI
             PUSH EBX
             PUSH ECX
             PUSH EDX

             PUSH DX
             MOV SI,DX           ;offset of logcal DOSBOOT
             MOV CX,WORD PTR DS:[SI+0BH]  ;bytes per setctor
             MOVZX ECX,CX
             MOV EBX,EAX
             ADD EAX,EBX         ;eax=offset of the cluster_no 
             XOR EDX,EDX
             DIV ECX             ;eax=sectors before the cluster_no 
             INC EAX             ;ADD boot now eax=logical sector_no
NEXT_CLUSTER1:                   ;EAX=sector_no of the cluster
             ;;;;;;;
             POP CX
             PUSH DX            ;remains = offset of cluster_no
             MOV DX,CX
             CALL READ_ONE_SECTOR
             MOV BX,OFFSET TTSECTOR
             POP DX
             ADD BX,DX
             MOV AX,DS:[BX]     ;next cluster
             MOVZX EAX,AX
             POP EDX
             POP ECX
             POP EBX
             POP SI
             RET
NEXT_CLUSTER ENDP

FIND_DIR    PROC FAR
            ;in:ttdw1 =start dir  ttdw2=end dir
            ;   ttsector_no =start logical sector_NO
            ;   rootdir_ls_NO = end logical sector_NO
            ;   ttdw6=end offset for dir_item
            ;   ttdw6=bytes_per_sector -32(480)
            ;out: ax=0 ->OK ax=1 not found
            ;use ttdw5 =start offset =(OFFSET TTSECTOR)
            ;    ttdw7 =end_total offset =(OFFSET TTSECTOR+ttdw6)

            ;;;;;;;;;;;;;;;;;;   loop read sector
            MOV AX,V_TOS_DATA_SEL 
            MOV DS,AX
            MOV ES,AX
            MOV AX,OFFSET TTSECTOR
            MOV BX,DS:TTDW6
            ADD AX,BX
            MOV DS:TTDW7,AX
FIND_DIR_1:   
            MOV EAX,DS:TTSECTOR_NO
            CMP EAX,DS:ROOTDIR_LS_NO  
            JA  FIND_DIR_END_ERROR
            INC DS:TTSECTOR_NO
            MOV  DX,OFFSET WORKBOOT
            CALL READ_ONE_SECTOR  ; read to ->ttsector
            ;;;;;;;;;;;;;;;;;;;;; find dir(=str2) in ttsector 
            CLD
            MOV SI,OFFSET TTSECTOR
            MOV DS:TTDW5,SI
FIND_DIR_10:
            MOV SI,DS:TTDW5
            CMP SI,DS:TTDW7
            JA  FIND_DIR_NEXT_SECTOR
            MOV CX,32
            ADD DS:TTDW5,CX
            MOV CX,11               ;DS:TTDW4
            MOV DI,OFFSET STR2
FIND_DIR_11:            
            CMPSB
            LOOPE FIND_DIR_11
            JE FIND_DIR_FOUND
            ;compare next
            JMP FIND_DIR_10
            ;;;;;;;;;;;;;;;;;;;;; find dir(=str2) in ttsector 

FIND_DIR_NEXT_SECTOR:
            JMP FIND_DIR_1
FIND_DIR_FOUND:
            MOV SI,DS:TTDW5          ;position of found dir
            SUB SI,32
FIND_DIR_FOUND_1:            
            MOV CX,32
            MOV DI,OFFSET DAT
            ADD DI,80
            REP MOVSB
            
            ;;;;;;;;;;;;;;;;;after found the dir-->start
            ;;;;;;;;;;;;;;;;;after found the dir-->end
            MOV AX,0
            JMP FIND_DIR_END
FIND_DIR_END_ERROR:
            MOV AX,1
FIND_DIR_END:
            RET
FIND_DIR    ENDP

FIND_DIR_FILE PROC FAR
            ; in: directory file is in v_file_buf_sel
            ;     dat is in v_tos_data_sel
            ;     STR2=NAME to find
            ; out:

            CALL FREAD_DAT
            ;save length of diretory file(CHIS) to ttdd1
            PUSH DS

            
            MOV AX,V_TOS_DATA_SEL 
            MOV DS,AX
            MOV EAX,DWORD PTR DS:TTDD1
            MOV CX,40
            MUL CX                     ;AX=offset of sft
            MOV SI,AX
            MOV DX,V_SFT_SEL
            MOV DS,DX
            MOV EDX,DWORD PTR DS:[SI+36]     ;write pointer of file

            MOV AX,V_TOS_DATA_SEL
            MOV DS,AX
            MOV DWORD PTR DS:TTDD1,EDX

            POP DS
            CMP EDX,0
            JLE FIND_DIR_FILE_ERROR
            ;save length of diretory file(CHIS) to ttdd1   ok!

            ;;;find 'ttt' in directory file:chis
            PUSH DS
            PUSH ES

            MOV AX,V_FILE_BUF_SEL
            MOV DS,AX
            MOV AX,V_TOS_DATA_SEL
            MOV ES,AX
            MOV DI,OFFSET STR2
            PUSH DI
            MOV CX,80
            MOV AL,0
            REPNZ SCASB
            MOV AX,DI
            POP DI
            SUB AX,DI
            DEC AX
            MOV ES:TTDW5,AX          ;end_offset    ok
            CLD
            MOV ESI,0
FIND_DIR_FILE_10:
            CMP ESI,DWORD PTR ES:ttdd1
            JAE  FIND_DIR_FILE_ERROR1
            MOV CX,11                 ;ES:TTDW5
            MOV DI,OFFSET STR2
            PUSH SI
            REPE CMPSB
            JE  FIND_DIR_FILE_FOUND
            POP SI
            ADD SI,32
            JMP FIND_DIR_FILE_10      ;compare next
FIND_DIR_FILE_FOUND:
            POP SI
            MOV CX,32
            MOV DI,OFFSET DAT
            ADD DI,80
            REP MOVSB
            MOV AX,0
            POP ES
            POP DS
            MOV AX,0
            JMP FIND_DIR_FILE_END

FIND_DIR_FILE_ERROR1:
            POP ES
            POP DS
FIND_DIR_FILE_ERROR:
            MOV AX,1
            ;;;;;;;;;;;;;;;;;;;;; find dir(=str2) in v_file_buf_sel
FIND_DIR_FILE_END:
            RET
            ;;;;;;;;;;;;;;;;;;;;; find dir(=str2) in v_file_buf_sel
FIND_DIR_FILE ENDP

FREAD  PROC FAR
       ;in: ds:dx address of buf cx=count to read  ax=handle   
       ;    es:bx address of opt
       ;out : cl=0 ok ax=real count have read 
       ;      cl=1 error ax=error_no
       ;CX AX will be changed
       PUSH EBP
       MOV EBP,ESP
       ADD EBP,4            ;ebp= ori esp

       PUSH SI
       PUSH DI
       ;;;;;;;;;;parameter into stack
       PUSH DS
       PUSH DX
       PUSH ES
       PUSH BX
       PUSH FS
       ;;;;;;;;;;;;;;;;;;;;;;;;;;;
       PUSH CX                 ;ebp -20
       ;;; GET file_len
       MOV SI,OFFSET OPT
       ADD SI,AX               ;SI=offset+handle=offset in sft
       MOV AX,ES:[SI]          ;ax=sft_no
       MOV CX,40
       XOR DX,DX
       MUL CX                  ;ax=offset of the handle in sft
       PUSH AX                 ;Paramter offset in sft
       MOV SI,AX               ;Paramter offset in sft     ebp-22

       ;;;; NOW have found the position in sft
       ; get file_len
       ; es change to sft
       MOV AX,V_SFT_SEL
       MOV ES,AX               ;ES:SI change to sft
       MOV AX,DS
       MOV GS,AX               ;GS:USER BUF
       MOV EAX,ES:[SI+19]      ; file_len
       PUSH EAX                ; reserve
       MOV AX,V_TOS_DATA_SEL 
       MOV FS,AX

⌨️ 快捷键说明

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