【原创】操作系统---文件系统设计(三)(你们需要的源代码)

本文作者分享了自己使用纯汇编语言创建的操作系统中文件系统的源代码。受到MenuetOS启发,尽管过程充满挑战,但作者通过这次经历提升了编程技能,尤其是面对复杂项目时不再畏惧。文章展示了系统的运行界面,并提及后续尝试制作图形界面。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

**作者注:**该文为我自创操作系统的全部源代码。之所以选择用纯汇编语言而非相对高级的语言来实现,则完全是处于一种对计算机硬件的信仰,因为我受到了大名鼎鼎的MenuetOS系统启发,感慨不已,膜拜万千。但是,写汇编语言的过程简直让人痛苦不堪,光要在屏幕上显示一个当前时间都足以让人崩溃。历时数月的工作,在完成了一个粗糙而又简单的文件操作系统之后(最终写入软盘的系统大小仅几K),我便停下来了,因为工作量实在太大了。但是这个痛并快乐的过程,让我收获很多,因为从此之后,其它再难的编程项目都没有比这个更难受的了,也便没有了理由做任何退缩。

;------该程序为自创的简易操作系统,并设计了一个简单的文件系统,支持目录和文件的创建\------
;------删除、复制、移动等简易操作。程序编译之后直接放到软盘便可引导一台裸机启动和运行,本人亲写并验证------
;------程序中注释掉的部分是在开发过程中的调试辅助输出信息。环境:nasm,虚拟机:vmware.------


NUMsector      EQU    8       ; 设置读取到的软盘最大扇区编号(18) 
NUMheader      EQU    0        ; 设置读取到的软盘最大磁头编号(01)
NUMcylind        EQU    0        ; 设置读取到的软盘柱面编号

mbrseg         equ    7c0h     ; 启动扇区存放段地址
loaderseg      equ    800h     ; 从软盘读取LOADER到内存的段地址

jmp   start

welcome db 'Welcome Jiang OS!','$'
fyread  db 'Now Floppy Read Loader:','$'
cylind  db 'cylind:?? $',0    ; 设置开始读取的柱面编号
header  db 'header:?? $',0    ; 设置开始读取的磁头编号
sector  db 'sector:?? $',2    ; 设置开始读取的扇区编号;第1扇区是MBR,可以不读
FloppyOK db '---Floppy Read OK','$'
Fyerror db '---Floppy Read Error' ,'$'
Fycontent db 'Floppy Content is:' ,'$'


start:

call showwelcome    ;初始化寄存器,打印必要信息
call loader         ;执行loader,把现在这张软盘的数据全部读到8000h开始。
jmp  loaderseg:0    ;跳转到内核。执行之后CS=loaderseg=800H,IP=0
                    ;内核程序从物理地址8000开始放


showwelcome:
     mov   ax,mbrseg
     mov   ds,ax   ;为显示各种提示信息做准备
     mov   ax,loaderseg
     mov   es,ax   ;为读软盘数据到内存做准备,因为读软盘需地址控制---ES:BX

     mov   si,welcome
     call  printstr
     call  newline
     ret

loader:
     mov   si, fyread
     call  printstr
     call  newline
     call  folppyload    ;将软盘的数据全部load到内存,从物理地址8000h开始
     ;mov   si, Fycontent
     ;call  printstr
     ;call  showdata      ;可以验证一下从软盘读入的kernal程序数据是否正确(二进制)
     ret


showdata:  mov  si,0             ;验证显示从软盘读取到内存的数据
           mov  ax, 800h
           mov  es,ax
           mov  cx,50             ;控制输出的数据长度
nextchar:  mov al,[es:si]
           mov ah,0eh
           int 10h
           inc si
           loop nextchar
           RET

folppyload:
     call    read1sector
     MOV     AX,ES
     ADD     AX,0x0020
     MOV     ES,AX                ;一个扇区占512B=200H,刚好能被整除成完整的段,因此只需改变ES值,无需改变BP即可。
     inc   byte [sector+11]
     cmp   byte [sector+11],NUMsector+1
     jne   folppyload             ;读完一个扇区
     mov   byte [sector+11],1
     inc   byte [header+11]
     cmp   byte [header+11],NUMheader+1
     jne   folppyload             ;读完一个磁头
     mov   byte [header+11],0
     inc   byte [cylind+11]
     cmp   byte [cylind+11],NUMcylind+1
     jne   folppyload             ;读完一个柱面

     ret


numtoascii:     ;将2位数的10进制数分解成ASII码才能正常显示。如柱面56 分解成出口ascii: al:35,ah:36
     mov ax,0
     mov al,cl  ;输入cl
     mov bl,10
     div bl
     add ax,3030h
     ret

readinfo:       ;显示当前读到哪个扇区、哪个磁头、哪个柱面
     mov si,cylind
     call  printstr
     mov si,header
     call  printstr
     mov si,sector
     call  printstr
     ret



read1sector:                      ;读取一个扇区的通用程序。扇区参数由 sector header  cylind控制

       mov   cl, [sector+11]      ;为了能实时显示读到的物理位置
       call  numtoascii
       mov   [sector+7],al
       mov   [sector+8],ah

       mov   cl,[header+11]
       call  numtoascii
       mov   [header+7],al
       mov   [header+8],ah

       mov   cl,[cylind+11]
       call  numtoascii
       mov   [cylind+7],al
       mov   [cylind+8],ah

       MOV        CH,[cylind+11]    ; 柱面从0开始读
       MOV        DH,[header+11]    ; 磁头从0开始读
       mov        cl,[sector+11]    ; 扇区从1开始读

        call       readinfo        ;显示软盘读到的物理位置
        mov        di,0
retry:
        MOV        AH,02H            ; AH=0x02 : AH设置为0x02表示读取磁盘
        MOV        AL,1            ; 要读取的扇区数
        mov        BX,    0         ; ES:BX表示读到内存的地址 0x0800*16 + 0 = 0x8000
        MOV        DL,00H           ; 驱动器号,0表示第一个软盘,是的,软盘。。硬盘C:80H C 硬盘D:81H
        INT        13H               ; 调用BIOS 13号中断,磁盘相关功能
        JNC        READOK           ; 未出错则跳转到READOK,出错的话则会使EFLAGS寄存器的CF位置1
           inc     di
           MOV     AH,0x00
           MOV     DL,0x00         ; A驱动器
           INT     0x13            ; 重置驱动器
           cmp     di, 5           ; 软盘很脆弱,同一扇区如果重读5次都失败就放弃
           jne     retry

           mov     si, Fyerror
           call    printstr
           call    newline
           jmp     exitread
READOK:    mov     si, FloppyOK
           call    printstr
           call    newline
exitread:
           ret


printstr:                  ;显示指定的字符串, 以'$'为结束标记
      mov al,[si]
      cmp al,'$'
      je disover
      mov ah,0eh
      int 10h
      inc si
      jmp printstr
disover:
      ret


newline:                     ;显示回车换行
      mov ah,0eh
      mov al,0dh
      int 10h
      mov al,0ah
      int 10h
      ret



times 510-($-$$) db 0
                 db 0x55,0xaa

;-------------------------------------------------------------------------------
;------------------此为扇区分界线,线上为第1扇区,线下为第2扇区-----------------
;-------------------------------------------------------------------------------
jmp    kernal

rdataseg         equ    1000h         ;从硬盘读取出的数据存放段地址 20000h     
wdataseg         equ    2000h         ;写进硬盘的数据存放段地址 800h为内核程序段地址,也即8000h。 

hdNUMsector      EQU   1      ; 设置读取到的硬盘最大扇区编号    最大:191
hdNUMheader      EQU   1      ; 设置读取到的硬盘最大磁头编号  最大:255 
hdNUMcylind      EQU   0       ; 设置读取到的硬盘柱面编号  最大:198 

whdNUMsector      EQU    2        ; 设置写到硬盘的最大扇区编号
whdNUMheader      EQU    0        ; 设置写到硬盘的最大磁头编号
whdNUMcylind      EQU    0        ; 设置写到硬盘的柱面编号

keralmsg   db 'Now You Have Comed Kernal!','$'
addrmsg    db 'Kernal Data Begins Address:8000h','$'
hdpara     db 'Now Hdisk Paras Read:','$'
hdwrite    db 'Now Hdisk Write Files:','$'
hdread     db 'Now Hdisk Read Files:','$'



pahdcylind  db 'cylind:?? $',0    ; 硬盘的柱面参数  0-6。共10bit,只取低8bit进行试验。 
pahdheader  db 'header:?? $',0    ; 硬盘的磁头参数  0-63
pahdsector  db 'sector:?? $',0    ; 硬盘的扇区参数  1-63
pahdOK      db '---Hdisk Paras Read OK','$'
pahderror   db '---Hdisk Paras Read Error' ,'$'



hdcylind  db 'cylind:?? $',0    ; 设置开始读取的柱面编号
hdheader  db 'header:?? $',0    ; 设置开始读取的磁头编号
hdsector  db 'sector:?? $',1    ; 设置开始读取的扇区编号
hdOK      db '---Hdisk Read OK','$'
hderror   db '---Hdisk Read Error' ,'$'  
hdcontent db 'Hdisk Content is:' ,'$'

whdcylind  db 'cylind:?? $',0    ; 设置开始写的柱面编号
whdheader  db 'header:?? $',0    ; 设置开始写的磁头编号
whdsector  db 'sector:?? $',1    ; 设置开始写的扇区编号
whdOK      db '---Hdisk Write OK','$'
whderror   db '---Hdisk Write Error' ,'$'

syscome    db '------------------------------------------------------',13,10,\
              'Now You Have Comed Jiang OS File System,Enjoy Youself!' ,13,10,\
              '------------------------------------------------------','$'
pwdinfo     db 'C:\>','$'
cdcom        db 'cd'
dircom       db 'dir'
clscom       db 'cls'
formatcom    db 'format'
mkdircom    db 'mkdir'              ;'deldir dir1????...'
deldircom    db 'deldir'   
inputcom    db '?????????????????'  ;'mkdir dir1????...' 
yescommsg    db 'True  Command','$'
nocommsg    db 'Bad   Command','$'
direrror    db 'Not Empty Directory,No Permited Delelte','$'
formatmsg   db 'Now Format Done,All Datas Lost!','$'

delname   db '????????'
bootname   db '/???????'
upname     db '..??????'
cdname     db '????????','$'       ;目录名最多8BIT
dirname    db '????????','$'       ;目录名最多8BIT 
filename  db '????????'

parentidmsg   db 'parentid:??','$'
diridmsg      db 'deldirid:??','$'

parentid   db -1 
dirid      db 0

deldirid   db 0
subdirid   db 0



kernal:     mov     ax,loaderseg     ;跳转到内核之后,全部寄存器启用新的段地址
                                     ;ES=CS=800H
            mov     es,ax              
            
            mov     ax,loaderseg
            sub     ax,20h
            mov     ds,ax            ;DS=800H-20H改变段地址之后,需要减去引导扇区的偏移量
                 
            mov     si, keralmsg  
            call    newline2
           call    printstr2
       
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值