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

📄 boot32.asm

📁 GNU FreeDOS兼容MS DOS很好的东东.
💻 ASM
字号:
;	+--------+;	|        |;	|        |;	|--------| 4000:0000;	|        |;	|  FAT   |;	|        |;	|--------| 2000:0000;	|BOOT SEC|;	|RELOCATE|;	|--------| 1FE0:0000;	|        |;	|        |;	|        |;	|        |;	|--------|;	|BOOT SEC|;	|ORIGIN  | 07C0:0000;	|--------|;	|        |;	|        |;	|        |;	|--------|;	|KERNEL  |;	|LOADED  |;	|--------| 0060:0000;	|        |;	+--------+;%define MULTI_SEC_READ  1segment	.text%define BASE            0x7c00                org     BASEEntry:          jmp     short real_start		nop;       bp is initialized to 7c00h%define bsOemName       bp+0x03      ; OEM label%define bsBytesPerSec   bp+0x0b      ; bytes/sector%define bsSecPerClust   bp+0x0d      ; sectors/allocation unit%define bsResSectors    bp+0x0e      ; # reserved sectors%define bsFATs          bp+0x10      ; # of fats%define bsRootDirEnts   bp+0x11      ; # of root dir entries%define bsSectors       bp+0x13      ; # sectors total in image%define bsMedia         bp+0x15      ; media descrip: fd=2side9sec, etc...%define sectPerFat      bp+0x16      ; # sectors in a fat%define sectPerTrack    bp+0x18      ; # sectors/track%define nHeads          bp+0x1a      ; # heads%define nHidden         bp+0x1c      ; # hidden sectors%define nSectorHuge     bp+0x20      ; # sectors if > 65536%define xsectPerFat     bp+0x24      ; Sectors/Fat%define xrootClst       bp+0x2c      ; Starting cluster of root directory%define drive           bp+0x40      ; Drive number		times	0x5a-$+$$ db 0%define LOADSEG         0x0060%define FATSEG          0x2000         %define fat_sector      bp+0x48         ; last accessed sector of the FAT%define loadsegoff_60	bp+loadseg_off-Entry ; FAR pointer = 60:0%define loadseg_60	bp+loadseg_seg-Entry%define fat_start       bp+0x5e         ; first FAT sector%define data_start      bp+0x62         ; first data sector%define fat_secmask     bp+0x66		; number of clusters in a FAT sector - 1%define fat_secshift    bp+0x68         ; fat_secmask+1 = 2^fat_secshift;-----------------------------------------------------------------------;   ENTRY;-----------------------------------------------------------------------real_start:     cld		cli                sub	ax, ax		mov	ds, ax                mov     bp, 0x7c00		mov	ax, 0x1FE0		mov	es, ax		mov	si, bp		mov	di, bp		mov	cx, 0x0100		rep	movsw           ; move boot code to the 0x1FE0:0x0000		jmp     word 0x1FE0:contloadseg_off	dw	0loadseg_seg	dw	LOADSEGcont:           mov     ds, ax                mov     ss, ax                lea     sp, [bp-0x20]		sti                mov     [drive], dl     ; BIOS passes drive number in DL;                call    print;                db      "Loading ",0;      Calc Params;      Fat_Start		mov	si, word [nHidden]		mov	di, word [nHidden+2]		add	si, word [bsResSectors]		adc	di, byte 0		mov	word [fat_start], si		mov	word [fat_start+2], di ;	Data_Start		mov	al, [bsFATs]		cbw		push	ax		mul	word [xsectPerFat+2]		add	di, ax		pop	ax		mul	word [xsectPerFat]		add	ax, si		adc	dx, di		mov	word[data_start], ax		mov	word[data_start+2], dx;      fat_secmask		mov	ax, word[bsBytesPerSec]		shr	ax, 1		shr	ax, 1		dec	ax		mov	word [fat_secmask], ax;      fat_secshift; cx = temp; ax = fat_secshift		xchg	ax, cx ; cx = 0 after movsw		inc	cxsecshift:	inc	ax		shr	cx, 1		cmp	cx, 1		jne	secshift		mov	byte [fat_secshift], al		dec	cx ;       FINDFILE: Searches for the file in the root directory.;;       Returns:;            DX:AX = first cluster of file                mov     word [fat_sector], cx           ; CX is 0 after "dec"                mov     word [fat_sector + 2], cx                mov     ax, word [xrootClst]                mov     dx, word [xrootClst + 2]ff_next_cluster:                push    dx                              ; save cluster                push    ax                call    convert_cluster                jc      boot_error                      ; EOC encountered                                ff_next_sector:                push    bx                              ; save sector count                les     bx, [loadsegoff_60]                call    readDisk                push    dx                              ; save sector                push    ax                mov     ax, [bsBytesPerSec]		; Search for KERNEL.SYS file name, and find start cluster.ff_next_entry:  mov     cx, 11                mov     si, filename                mov     di, ax                sub     di, 0x20                repe    cmpsb                jz      ff_done                sub     ax, 0x20                jnz     ff_next_entry                pop     ax                      ; restore  sector                pop     dx                pop     bx                      ; restore sector count                dec     bx                jnz     ff_next_sectorff_find_next_cluster:                pop     ax                      ; restore current cluster                pop     dx                call    next_cluster                jmp     short ff_next_clusterff_done:                                mov     ax, [es:di+0x1A-11]        ; get cluster number                mov     dx, [es:di+0x14-11]c4:                sub     bx, bx                  ; ES points to LOADSEG      c5:             push    dx                push    ax                push    bx                call    convert_cluster                jc      boot_success                mov     di, bx                pop     bxc6:                call    readDisk                dec     di                jnz     c6                pop     ax                pop     dx                call    next_cluster                jmp     short c5                boot_error:		xor	ah,ah		int	0x16			; wait for a key		int	0x19			; reboot the machine; input: ;    DX:AX - cluster; output:;    DX:AX - next cluster;    CX = 0; modify:;    DInext_cluster:                  push    es                mov     di, ax                and     di, [fat_secmask]                                mov     cx, [fat_secshift]cn_loop:                shr     dx,1                rcr     ax,1                dec     cx                jnz     cn_loop                ; DX:AX fat sector where our                                               ; cluster resides                                               ; DI - cluster index in this                                               ; sector                                                               shl     di,1                   ; DI - offset in the sector                shl     di,1                add     ax, [fat_start]                adc     dx, [fat_start+2]      ; DX:AX absolute fat sector                push    bx                mov     bx, FATSEG                mov     es, bx                sub     bx, bx                cmp     ax, [fat_sector]                jne     cn1                    ; if the last fat sector we                                               ; read was this, than skip                cmp     dx,[fat_sector+2]                je      cn_exitcn1:                mov     [fat_sector],ax        ; save the fat sector number,                mov     [fat_sector+2],dx      ; we are going to read                call    readDiskcn_exit:                pop     bx                mov     ax, [es:di]             ; DX:AX - next cluster                mov     dx, [es:di + 2]         ;                pop     es                retboot_success:                   mov     bl, [drive]		jmp	far [loadsegoff_60]; Convert cluster to the absolute sector;input:;    DX:AX - target cluster;output:;    DX:AX - absoulute sector;    BX - [bsSectPerClust];modify:;    CXconvert_cluster:                cmp     dx,0x0fff                jne     c3                cmp     ax,0xfff8                jb      c3              ; if cluster is EOC (carry is set), do ret                stc                retc3:                mov     cx, dx          ; sector = (cluster - 2)*clussize +                                        ; + data_start                sub     ax, 2                sbb     cx, byte 0           ; CX:AX == cluster - 2                mov     bl, [bsSecPerClust]                sub     bh, bh                xchg    cx, ax          ; AX:CX == cluster - 2                mul     bx              ; first handle high word                                        ; DX must be 0 here                xchg    ax, cx          ; then low word                mul     bx                add     dx, cx                          ; DX:AX target sector                add     ax, [data_start]                adc     dx, [data_start + 2]                ret; prints text after call to this function.print_1char:                        xor   bx, bx                   ; video page 0                mov   ah, 0x0E                 ; else print it                int   0x10                     ; via TTY modeprint:          pop   si                       ; this is the first characterprint1:         lodsb                          ; get token                push  si                       ; stack up potential return address                cmp   al, 0                    ; end of string?                jne   print_1char              ; until done                ret                            ; and jump to it                ;input:;   DX:AX - 32-bit DOS sector number;   ES:BX - destination buffer;output:;   ES:BX points one byte after the last byte read.;   DX:AX - next sector;modify:;   ES if DI * bsBytesPerSec >= 65536, CXreadDisk:read_next:      push    dx                push    ax                ;                ; translate sector number to BIOS parameters                ;                ;                ; abs = sector                          offset in track                ;     + head * sectPerTrack             offset in cylinder                ;     + track * sectPerTrack * nHeads   offset in platter                ;                xchg    ax, cx                mov     al, [sectPerTrack]                mul     byte [nHeads]                xchg    ax, cx                ; cx = nHeads * sectPerTrack <= 255*63                ; dx:ax = abs                div     cx                ; ax = track, dx = sector + head * sectPertrack                xchg    ax, dx                ; dx = track, ax = sector + head * sectPertrack                div     byte [sectPerTrack]                ; dx =  track, al = head, ah = sector                mov     cx, dx                ; cx =  track, al = head, ah = sector                ; the following manipulations are necessary in order to                ; properly place parameters into registers.                ; ch = cylinder number low 8 bits                ; cl = 7-6: cylinder high two bits                ;      5-0: sector                mov     dh, al                  ; save head into dh for bios                xchg    ch, cl                  ; set cyl no low 8 bits                ror     cl, 1                   ; move track high bits into                ror     cl, 1                   ; bits 7-6 (assumes top = 0)                inc     ah                      ; sector offset from 1                or      cl, ah                  ; merge sector into cylinder                mov     ax, 0x0201                mov     dl, [drive]                int     0x13                pop     ax                pop     dx                         jnc     read_ok                 ; jump if no error                xor     ah, ah                  ; else, reset floppy                int     0x13                jmp     short read_nextread_ok:                add     bx, word [bsBytesPerSec]                jnc     no_incr_es              ; if overflow...                mov     cx, es                add     ch, 0x10                ; ...add 1000h to ES                mov     es, cxno_incr_es:                add     ax,byte 1                adc     dx,byte 0                ret       times   0x01f1-$+$$ db 0filename        db      "KERNEL  SYS",0,0sign            dw      0xAA55

⌨️ 快捷键说明

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