【汇编】手把手教你打造自己的第一个操作系统


将操作系统写入软盘,并以软盘启动的方式开启操作系统。实现重启计算机,引导现有操作系统,显示及设置时钟(即所谓的操作系统偷笑)。调试阶段在vmware+msdos下完成。

实验提示:

1、为了方便我们在虚拟机下进行实验,我选择vmware;

2、为了调试方便我们安装MS-DOS 7.10(自带DEBUG),下载地址:http://www.onlinedown.net/soft/2465.htm

3、下载并安装masm6.11(包括masm及link),下载地址:http://ishare.iask.sina.com.cn/f/11460493.html?from=like

4、向虚拟主机内的DOS传文件可以选择光盘和软盘两种。可以用UltraISO制作。下载地址:http://www.crsky.com/soft/1134.html

5、为了选择软盘启动我们可以让虚拟机延时进入操作系统。打开MS-DOS.vmx,加入bios.bootDelay = "10000"

效果图:

以下是全部代码:

assume cs:code code segment ;安装程序 start: mov ax,cs mov es,ax mov bx,offset sec1 mov ah,3 mov al,9 mov ch,0 mov cl,1 mov dl,0 mov dh,0 int 13h mov ax,4c00h int 21h ;第一扇区 ;读第二扇区到0:7e00h sec1: ;mov ax,0 ;mov es,ax ;mov bx,7e00h mov ax,1000h mov es,ax mov bx,7e00h mov ah,2 mov al,9 mov ch,0 mov cl,2 mov dl,0 mov dh,0 int 13h ;跳转到0:7e00h ;mov ax,0 ;push ax ;mov ax,7e00h ;push ax ;retf mov ax,1000h push ax mov ax,7e00h push ax retf db 512-($-sec1)-2 dup(0) dw 0aa55h ;第二扇区 sec2: jmp sec2start intro: db '*****************************************************' db '*** press 1 to restart system ***' db '*** press 2 to start current system ***' db '*** press 3 to start clock ***' db '*** press 4 to setting clock ***' db '*****************************************************' err_not_support_op: db 'not support operation!' opt: db 0 ;接收输入的变量 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;newline,showstr,get_str的使用方法请见: ;; ;;http://blog.csdn.net/xiaodao1986/article/details/6724050 ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;换行(当前行的下一行) newline:push ax push bx push cx push dx mov ah,03h mov bh,0 int 10h cmp dh,24 jb incrow mov ah,06h mov al,1 mov bh,07h mov ch,0 mov cl,0 mov dh,24 mov dl,80 int 10h jmp changerow incrow: inc dh changerow: mov ah,2 mov bh,0 mov dl,0 int 10h nrtn: pop dx pop cx pop bx pop ax ret ;在当前行显示字符串(80*25) ;@param ds:si - 变量地址 ;@param cx - 变量长度 showstr:push ax push bx push cx push dx push es push di push si push cx mov ah,03h mov bh,0 int 10h pop cx mov ax,0b800h mov es,ax mov al,160 mul dh mov di,ax mov bx,0 mov dl,0 s: mov al,ds:[si] cmp al,0 jne _if mov byte ptr es:[bx+di],' ' jmp short _endif _if: mov byte ptr es:[bx+di],al inc dl _endif: inc si add bx,2 loop s mov ah,2 mov bh,0 int 10h pop si pop di pop es pop dx pop cx pop bx pop ax ret ;获取用户输入 ;@param ds:si - 变量地址 ;@param cx - 变量长度 get_str:push ax push bx push cx push dx push si mov bx,si mov dx,0 push cx push si s1: mov byte ptr ds:[si],0 inc si loop s1 pop si pop cx get: mov ah,0 int 16h cmp ah,1ch je gtrn cmp ah,0eh je delchar cmp dx,cx jnb get mov byte ptr ds:[si],al inc si inc dx jmp gshowstr delchar:cmp si,bx jna get dec si dec dx mov byte ptr ds:[si],0 jmp gshowstr gshowstr: push si mov si,bx call showstr pop si jmp get gtrn: call newline pop si pop dx pop cx pop bx pop ax ret ;子程序一:重启计算机 resetpc:mov ax,0ffffh push ax mov ax,0 push ax retf ;子程序二:引导现有系统 startsys: mov ax,0 mov es,ax mov bx,7c00h mov ah,2 mov al,1 mov ch,0 mov cl,1 mov dh,0 mov dl,80h int 13h mov ax,0 push ax mov ax,7c00h push ax retf ;子程序三:时钟程序 ;时钟程序,按ESC退出 ;@param cl - 行 ;@param ch - 列 clock: jmp clockstart table: db 9,8,7,4,2,0 timestr: db 0,0,'/',0,0,'/',0,0,' ',0,0,':',0,0,':',0,0 clockstart: push ax push bx push cx push dx push si push di push ds push es call {1}3 ofst: pop ax ;ip mov bx,ofst - table sub ax,bx mov si,ax mov ax,cs mov ds,ax mov di,si add di,6 for_clock: push si push di push cx mov cl,4 mov ch,0 for_clock2: mov al,ds:[si] mov dx,70h out dx,al in al,71h mov ah,al shr ah,cl add ah,30h mov byte ptr ds:[di],ah inc di and al,00001111b add al,30h mov byte ptr ds:[di],al add di,2 inc si inc ch cmp ch,6 je show_time jmp for_clock2 show_time: pop cx pop di pop si push si push di push cx mov ax,0b800h mov es,ax mov si,di mov al,160 mul cl mov di,ax mov al,2 mul ch add di,ax mov cx,17 for_getchr: mov al,ds:[si] mov ah,07h mov es:[di],ax inc si add di,2 loop for_getchr pop cx pop di pop si check: in al,60h cmp al,01h je clockrtn jmp for_clock clockrtn: pop es pop ds pop di pop si pop dx pop cx pop bx pop ax ret ;子程序四:设置时钟 setclock: jmp scstart var_sc_time: db 17 dup(0) sc_tip: db 'set time with format $/$/$ $:$:$,eg.11/09/05 11:14:20' sc_table: db 9,8,7,4,2,0 scstart:push ax push ds push bx push si push di push cx push dx ;动态设置ds,si,di call scofst scofst: pop ax ;ip mov bx,scofst - var_sc_time sub ax,bx mov si,ax mov di,ax mov ax,cs mov ds,ax ;显示提示字符串 mov cx,sc_table - sc_tip add si,sc_tip - var_sc_time call showstr call newline ;获取用户输入 mov si,di mov cx,sc_tip - var_sc_time call get_str ;处理用户输入 add si,sc_table - var_sc_time mov cx,6 for_sc: mov word ptr dx,ds:[di] mov al,ds:[si] push cx sub dl,30h mov cl,4 shl dl,cl sub dh,30h or dh,dl out 70h,al mov al,dh out 71h,al pop cx inc si add di,3 loop for_sc pop dx pop cx pop di pop si pop bx pop ds pop ax ret ;主程序 sec2start: ;mov ax,0 mov ax,1000h mov ds,ax mov cx,53 mov si,7e00h + offset intro - offset sec2 mov bl,6 ;显示操作说明 for_intro: call showstr call newline add si,53 dec bl cmp bl,0 je end_for_intro jmp for_intro end_for_intro: ;获取用户输入 mov si,7e00h + offset opt - offset sec2 mov cx,1 call get_str ;=1,重启计算机 cmp byte ptr ds:[si],31h je resetpc ;=2,引导现有系统 cmp byte ptr ds:[si],32h je startsys ;=3,进入时钟程序 cmp byte ptr ds:[si],33h je call_clock ;=4,设置时钟 cmp byte ptr ds:[si],34h je call_setclock ;不支持用户输入的操作,显示错误消息,并等待用户的下一个输入 mov si,7e00h + offset err_not_support_op - offset sec2 mov cx,22 call showstr call newline jmp end_for_intro call_clock: mov cl,8 mov ch,60 call clock jmp end_for_intro call_setclock: call setclock jmp end_for_intro code ends end start
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值