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


将操作系统写入软盘,并以软盘启动的方式开启操作系统。实现重启计算机,引导现有操作系统,显示及设置时钟(即所谓的操作系统偷笑)。调试阶段在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
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值