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

📄 load.asm

📁 操作系统实验教程核心技术与编程实例书中地例子代码
💻 ASM
字号:
CODE        SEGMENT PARA USE16         ;can't run alone
            ASSUME CS:CODE
            ORG 800H
START:      
            .386P
            ;MOV AX,0600H         ;clear screen
            ;MOV BH,07H
            ;MOV CX,0
            ;MOV DX,184FH
            ;INT 10H
            MOV AX,1301H         ;M1
            MOV DX,0A00H
            MOV BX,7H
            MOV BP,OFFSET M1
            MOV SI,BP
            MOV CL,[SI]
            XOR CH,CH
            INC BP
            INT 10H
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAAAAAAA
            ;load the file "GFAT16.EXE" to 1000:0 
            MOV  SI,7C00H          ;COS_BOOT sector moved to 70:0
            MOV  DI,700H
            MOV  CX,03EH
            REPZ MOVSB

            MOV  SI,700H
            XOR AX,AX
            CMP [SI+13H],AX
            JZ  L1
            MOV CX,[SI+13H]
            MOV [SI+20H],CX
L1:         MOV AL,[SI+10H]
            MUL WORD PTR [SI+16H]
            ADD AX,[SI+0EH]
            ADC DX,+0
            MOV WORD PTR DIR_FS+7,AX  ;7C50 save root dir 1st sector_no
            MOV WORD PTR DIR_FS+9,DX  ;7C52
            MOV WORD PTR DIR_FS,AX    ;7C49
            MOV WORD PTR DIR_FS+2,DX  ;7C4B
            MOV AX,20H
            MUL WORD PTR [SI+11H]     ;dx:ax bytes of root_dir
            MOV BX,[SI+0BH]           ;bx=bytes per sector
            ADD AX,BX
            DEC AX
            DIV BX
            ADD WORD PTR DIR_FS,AX   ;save file area 1st sector_no
            ADC WORD PTR DIR_FS+2,+0
            MOV DX,WORD PTR DIR_FS+9 ;7c52h
            MOV AX,WORD PTR DIR_FS+7 ;7c50h   dx:ax  root dir 1st sector_no
            CALL SECTOR_ADDR
            JB  ERROR_IN
            MOV AL,1
            MOV BX,0500H             ;input buf----root 1st sector
            CALL READ_SECTOR         ;gfat16.exe should be in 1st sector
            JB  ERROR_IN
            MOV BL,16
            cld
            MOV WORD PTR DIR_FS+13,SI
            MOV DI,0500H
L2:         MOV CX,000BH
            MOV WORD PTR DIR_FS+15,DI
            MOV SI,OFFSET FNAME0
            REPZ CMPSB
            JZ  READ_OK
            DEC BL
            JZ  ERROR_IN
            MOV DI,WORD PTR DIR_FS+15
            ADD DI,32
            JMP L2
            
READ_OK:    ;found GFAT16.EXE di point just after file_name
            MOV SI,WORD PTR DIR_FS+13
            MOV AX,DI
            ADD AX,15
            MOV DI,AX   
            MOV AX,[DI]         ;begin cluster_no
            MOV WORD PTR DIR_FS+17,AX  ;cluster_no
            MOV BX,0H
            MOV WORD PTR DIR_FS+19,BX  ;offset of Input buf
            ; read GFAT16.EXE--->1000H:0 
            ; in:DIR_FS+17=1st cluster_no
            ;  & DIR_FS+19=offset of Input buf   
            ;from cluster -->logical sector_no
CLUSTER_L:  MOV SI,700h
            MOV AX,WORD PTR DIR_FS+17
            CMP AX,0FFF8H
            JAE READ_FILE_END
            XOR DX,DX
            SUB AX,2
            MOV BL,BYTE PTR [SI+0DH]
            XOR BH,BH
            MUL BX
            ADD AX,WORD PTR DIR_FS
            ADC DX,+0         ;dx:ax logical sector_no
            ; Read gfat16.exe
READ_FILE:  
            ;MOV WORD PTR DIR_FS,AX
            ;MOV WORD PTR DIR_FS+2,DX
            CALL SECTOR_ADDR
            JB  ERROR_IN
            MOV AL,BYTE PTR [SI+0DH]
            PUSH ES
            MOV BX,1000H
            MOV ES,BX
            MOV BX,WORD PTR DIR_FS+19
            CALL READ_SECTOR         ;cos.exe should be in 1st sector
            JB  ERROR_IN0
            JMP READ_FILE_NEXT
ERROR_IN0:  POP ES
            JMP ERROR_IN
READ_FILE_NEXT:
            POP ES
            ;************find next cluster_start
            PUSH EBX
            PUSH ECX
            PUSH EDX
            MOV CX,WORD PTR DS:[SI+0BH]  ;bytes per setctor
            MOVZX ECX,CX
            MOV AX,WORD PTR DIR_FS+17    ;current cluster
            MOVZX EAX,AX
            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
             ;;;;;;;
            PUSH DX            ;remains = offset of cluster_no
            ;read one_sector eax=logical sector_no
            MOV EDX,EAX
            SHR EDX,16
            CALL SECTOR_ADDR
            JB  ERROR_IN
            MOV AL,1
            MOV BX,OFFSET TTSECTOR
            CALL READ_SECTOR         ;read fat
            JB  ERROR_IN1
            JMP READ_FILE_NEXT1
ERROR_IN1:  
            JMP ERROR_IN
READ_FILE_NEXT1:
            ;read one_sector eax=logical sector_no
            MOV BX,OFFSET TTSECTOR
            POP DX      ;remains
            ADD BX,DX
            MOV AX,[BX]     ;next cluster
            CLD
            MOV WORD PTR DIR_FS+17,AX
            POP EDX
            POP ECX
            POP EBX
            ;************find next cluster_end
            MOV AL,[SI+0DH]
            MOV AH,0
            MUL WORD PTR [SI+0BH]
            CLD
            ADD WORD PTR DIR_FS+19,AX
            JMP CLUSTER_L
READ_FILE_END:
            MOV AX,1000H
            MOV GS,AX
            CALL G_EXEC_LOAD
            CMP AX,1
            JE ERROR_IN
            ;
            CLI
            MOV AX,GS:0EH
            MOV SS,AX
            MOV AX,GS:11H
            MOV SP,AX
            STI
            ;MOV BX,GS:16H
            ;ADD BX,1000H
            ;MOV SI,GS:14H

DB 0EAH
DW 0,1CDFH         ;for ok  1000+20+CBF=cos.exe

jmp ttt

ERROR_IN:   MOV BP,OFFSET ERROR1
            CALL DO_ERROR
;tt:         jmp tt           ;cut off comment
TTT:                          ;cut off after test
MOV ax,4c00h        ;for test
int 21h

T1:         JMP T1  ; ok
mov ax,word ptr dir_fs+17
CALL DISP_EXT_AX_dos
mov ax,word ptr dir_fs+19
CALL DISP_EXT_AX_dos

READ_SECTOR PROC NEAR
            ;in:es:bx input buf
            ;ds:dir_fs   ds=0
            MOV AH,2
            MOV DX,WORD PTR DIR_FS+4 ;cylinder=7C4D
            MOV CL,6
            SHL DH,CL
            OR  DH,DIR_FS+6          ;sector=7C4F
            MOV CX,DX
            XCHG CH,CL
            MOV DL,[SI+24H]
            MOV DH,[SI+25H]         ;head
            INT 13H
            RET
READ_SECTOR ENDP

SECTOR_ADDR PROC NEAR
            ;in : dx:ax= logical sector_no
            ADD AX,1
            ADC DX,+0
            ADD AX,[SI+1CH]
            ADC DX,[SI+1EH]       ;DX:AX =A
            PUSH AX
            PUSH DX
            MOV AX,[SI+1AH]
            MUL WORD PTR [SI+18H]
            MOV WORD PTR DIR_FS+11,AX
            POP DX
            POP AX
            DIV WORD PTR DIR_FS+11
            MOV WORD PTR DIR_FS+4,AX        ;Cylinder_no
            XCHG AX,DX   
            XOR DX,DX
            DIV WORD PTR [SI+18H]
            MOV [SI+25H],AL        ;head_no
            MOV DIR_FS+6,DL        ;Sector_no 7C4f
            CLC
            RET
EEE:        STC
            RET 
SECTOR_ADDR ENDP
DO_ERROR    PROC NEAR
            MOV AX,1301H         ;display M1
            MOV DX,0A00H
            MOV BX,7H
            ;MOV BP,OFFSET ERROR1
            MOV SI,BP
            MOV CL,[SI]
            XOR CH,CH
            INC BP
            INT 10H
;DO_ERROR0:   JMP DO_ERROR0     ;OK after test
            RET
DO_ERROR    ENDP
;;;;;;;;;;;AAAAAAAAA
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
G_EXEC_LOAD PROC FAR
            ;in---- (ds)=system data segment
            ;       (gs)=head+program(cos.exe)=1000H
            ;       DS:G_WORK 100 DB PARA AREA
            PUSH ES
            MOV BX,GS:00H
            CMP BX,5A4DH
            JZ  G_EXEC0
            MOV AX,1           ;Not DOS .exe  first 2 bytes is 4D5AH
            JMP G_EXEC_END
            ;*********************get program_size
G_EXEC0:    
            ;                    set ldt_desc for CS OF USER PROCESS  -->START
            MOV AX,GS:08H       ;SIZE_HEAD PARA
            SHL AX,4            ;SIZE_HEAD BYTE
            PUSH AX             ;SS:1=SIZE_HEAD BYTE INTO STACK
            ;;;;;;;;;           ;GET FILE_SIZE
            MOV BX,GS:02H       ;mod512
            MOV AX,GS:04H       ;file_sectors
            CMP BX,0
            JZ  g_exec1
            DEC AX
g_exec1:    XOR DX,DX
            MOV CX,512
            MUL CX         
            ADD AX,BX      
            ADC DX,0            ;DX:AX  file_size
            MOV DS:G_WORK,AL       
            MOV DS:G_WORK[1],AH      
            MOV DS:G_WORK[2],DL
            MOV DS:G_WORK[3],DH ;0-3=FILE SIZE
            POP BX              ;GET SIZE_HEAD 
            ;PUSH BX
            MOVZX EBX,BX
            MOV DWORD PTR DS:G_WORK[4],EBX   ;4-7=SIZE_HEAD 
            MOV CX,WORD PTR GS:6H            ;reposit_count  LOOP
            MOV BX,WORD PTR GS:18H           ;position for re_position item
g_exec_1:   
            MOV AX,WORD PTR GS:[BX]
            ADD AX,WORD PTR DS:G_WORK[4]    ;OFFFSET
            MOV DI,AX
            MOV AX,WORD PTR GS:[BX+2]
            ADD AX,1000H
            MOV ES,AX

            MOV AX,ES:[DI]
            ADD AX,1000H
            ADD AX,GS:08H
            MOV ES:[DI],AX
            ADD BX,4
            LOOP g_exec_1
G_EXEC_END1:
            ;                  LOOP OTHER SEGMENT-----END
            ;POP DX
            ;*********************A  -->end   deal with loading .exe
G_EXEC_END: 
            POP ES
            RET
G_EXEC_LOAD ENDP

;call DISP_EXT_AX_dos
;jmp G_EXEC_END1

M1          DB 17,'Start NUAA 3G-COS'
FNAME0      DB 'COS     EXE'
ERROR1      DB 15H,'Non-System disk error'
ERROR2      DB 10H,'Error loading OS'  
DIR_FS      DB 21 DUP(0)
G_WORK      DB 100 DUP(0)
TTSECTOR    DB 512 DUP(?)
t_string    DB 100 DUP(0)
G_END:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;xxxxxxxxxxxxxx next for test
DISP2_16_dos    PROC FAR
            ;in al code 2 using ah
            ;out ah:al:code 16
            mov ah,al
            MOV CL,4
            shr ah,CL
            cmp ah,9
            jle disp2_16_1_dos
            add ah,7    
disp2_16_1_dos: add ah,30h
            and al,0fh
            cmp al,9
            jle disp2_16_2_dos
            add al,7
disp2_16_2_dos: add al,30h
            RET
DISP2_16_dos    ENDP

DISP_EXT_AX_dos PROC FAR
            ;in cx:position
            PUSH AX
            PUSH BX
            PUSH CX
            PUSH DX

            MOV BX,AX
            mov al,BH
            CALL DISP2_16_dos
            mov DS:t_string,ah
            mov DS:t_string[1],al
            MOV AL,BL
            CALL DISP2_16_dos
            mov DS:t_string[2],ah
            mov DS:t_string[3],al
            mov DS:t_string[4],' '
            mov DS:t_string[5],'$'
            MOV AH,9
            MOV DX,OFFSET t_string
            ;add dx,16
            INT 21H
            POP DX
            POP CX
            POP BX
            POP AX
            RET
DISP_EXT_AX_dos     ENDP
;;xxxxxxxxxxxxxx next for test

START_TEST:
            CLI
            MOV  AX,SEG CODE
            MOV  SS,AX
            MOV  AX,OFFSET STACK0
            ADD  AX,1024
            MOV  SP,AX
            MOV  AX,SEG CODE
            MOV  ES,AX
            MOV  DS,AX
            CLD

            ;;;;;;;;;;;;;;;;;;;;; save to C:\TC\G\LOAD.3G
            MOV DX,OFFSET FNAME
            MOV CX,0
            MOV AH,3CH     ;CREAT FILE
            INT 21H
            MOV AL,01H     ;FOR WRITE
            MOV AH,3DH     ;OPEN FILE
            INT 21H
            MOV BX,AX      ;BX=FILE HANDLE
            MOV DX,OFFSET START
            MOV CX,start_test ; OFFSET G_END   ;for test     1/1
            SUB CX,DX
            MOV AH,40H     ;WRITE FILE
            INT 21H
            MOV AH,3EH     ;CLOSE FILE
            INT 21H

            MOV AX,4C00H
            INT 21H

FNAME       DB 'C:\TC\G\LOAD.3G',0
STACK0      DB 1024 DUP(?)
CODE        ENDS
END START_TEST

⌨️ 快捷键说明

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