8086汇编,系统引导程序(有注释),《汇编语言》-王爽-课程设计2

先来看看效果图吧 

 

 

本实验 来源于《汇编语言》-王爽,本次课设在XP系统下进行,若要测试请安装虚拟机XP系统

这是汇编实现的源代码,我也是初学汇编,有什么写的不好的地方请见谅

assume cs:code
code segment
	start:

	mov ax,cs
	mov es,ax
	mov bx,offset mpc

	mov al,6	;xie扇区数
	mov ch,0	;磁道号	
	mov cl,1	;扇区号
	mov dl,0	;驱动器号
	mov dh,0	;磁头号
			;es:bx指向从内存写入扇区的内存地址

	mov ah,3	;ah为功能号 3为写扇区 2为读扇区
	int 13h

	
	mov ax,4c00h
	int 21h

mpc:
	jmp  mstart
	dw offset charpush-offset mpc+7c00h,offset charpop-offset mpc+7c00h,offset charshow-offset mpc+7c00h
	dw 0	;栈顶
	db 32 dup(0)	;栈中的字符
	db '1) reset pc    ',0

	db '2) start system',0

	db '3) clock       ',0

	db '4) set clock   ',0	

	dw 0,0,0,0,0,0 ;年月日,时分秒	88+16
	db 9,8,7,4,2,0	;119
	db 'F1 to charge color, ESC to end',0	;125
	db 'year/month/day/hour/minute/sec,press enter to continue',0;122+31	
	db 'Input function number and press enter to confirm ',0 ;125+31+55
	
mstart:
	mov ax,0
	mov es,ax
	mov bx,7c00h+512

	mov al,5	;读取扇区数
	mov ch,0	;磁道号	
	mov cl,2	;扇区号
	mov dl,0	;驱动器号
	mov dh,0	;磁头号
			;es:bx指向从扇区读入的内存区

	mov ah,2	;ah为功能号 3为写扇区 2为读扇区
	int 13h
  mpcstart:
	mov dh,4
	mov dl,0
	mov bx,125+31+55+7c00h	;############
	call ackshowstr

	call showchoice
	call getstr
	mov ah,cs:[8+7c00h+3]	;字符存储地址##################

	cmp ah,'3'
	je clockcall

	cmp ah,'4'
	je setclockcall

	cmp ah,'1'
	je resetpc

	cmp ah,'2'
	je startsyscall
	
	jmp mpcstart


clockcall:
	call clearhint
	call clock
	jmp mpcstart
setclockcall:
	call clearhint
	call setclock
	jmp mpcstart
startsyscall:
	call startsys

;///clearhint
clearhint:
	push ax
	push bx
	push cx
	push es
	mov ax,0b800h
	mov es,ax
	mov bx,4*160
	mov cx,64
  hintloop:
	mov byte ptr es:[bx],0
	add bx,2
	loop hintloop
	pop es
	pop cx
	pop bx
	pop ax
	ret

;///1号功能 重启计算机
resetpc:
	mov word ptr ds:[0],0
	mov word ptr ds:[2],0ffffh
	jmp dword ptr ds:[0]		;计算机重启地址############


;///3号功能 显示时间
clock:
	push ax
	push bx
	push cx
	push dx

	mov dh,4
	mov dl,0
	mov bx,125+7c00h		;############
	call ackshowstr

	call getclockime
	call showclocktime


	mov cx,cs:[98+16+7c00h+3]	;秒地址############	
	mov bx,1
    clocks0:
	call isquit
	cmp bx,0
	je clockend
	call getclockime
	mov dx,cs:[98+16+7c00h+3]	;秒地址##########
	cmp cx,dx
	jne clocknext0
	jmp clocks0
    clocknext0:
	call showclocktime
	mov cx,dx
	jmp clocks0
	
  clockend:
	mov bl,2	;调用ack提示并等待回车
	call ack
	pop dx
	pop cx
	pop bx
	pop ax
	ret

getclockime:		;获取时间

	push cx
	push ax
	push si
	push di
	push ds
	push es
	push bx
	push dx

	mov si,100+16+7c00h+3	;时间信息端口读取地址####
	mov di,88+16+7c00h+3	;存储时间地址#########
	mov cx,6

     s:	
	push cx
	mov al,cs:[si]
	out 70h,al
	in al,71h

	mov ah,al
	mov cl,4
	shr ah,cl
	and al,00001111b
		
	add ah,30h
	add al,30h
	
	mov cs:[di],ah
	mov cs:[di+1],al
	
	inc si
	add di,2

	pop cx
	loop s

	pop dx
	pop bx
	pop es
	pop ds
	pop di
	pop si
	pop ax
	pop cx
	ret

showclocktime:		;显示时间

	push cx
	push ax
	push si
	push di
	push ds
	push es
	push bx
	push dx

	mov ax,0b800h
	mov es,ax
	mov si,5*160

	mov di,88+16+7c00h+3	;时间地址#######
	mov cx,6	

    s1:
	mov  ah,cs:[di]
	mov es:[si],ah
	add si,2
	inc di

	mov  ah,cs:[di]
	mov es:[si],ah
	add si,2
	inc di
	
	cmp cx,1
	je ed
	cmp cx,3
	jna s2
	mov al,2fh	;/
	jmp next
     s2:
	mov al,3ah	;:
    next:
	mov  es:[si],al
	add si,2
	loop s1
   ed:
	pop dx
	pop bx
	pop es
	pop ds
	pop di
	pop si
	pop ax
	pop cx
	ret

isquit:		;bx0退出  bx为1继续 
	push ax
	push cx

	in al,60h
	cmp al,01h	;若为esc 退出循环
	je yesquit
	cmp al,3bh	;若为f1 改变颜色
	je changecolor

	mov bx,1
	jmp isquitend

	
  yesquit:
	mov bx,0
	jmp isquitend

  changecolor:
	mov si,5*160+1
	mov ax,0b800h
	mov es,ax
	mov cx,17
  chagecolors:
	cmp byte ptr es:[si],7
	ja clearzero
	inc byte ptr es:[si]
     chagenext:
	add si,2
	loop chagecolors
	mov bx,1
	jmp  isquitend

  clearzero:
	mov byte ptr es:[si],1
	jmp chagenext

  isquitend:
	pop cx
	pop ax
	ret
;///4号功能  设置时间 设置格式 19/12/13/12:51:42
setclock:

	push cx
	push ax
	push si
	push di


	mov dh,4
	mov dl,0
	mov bx,125+31+7c00h  ;############
	call ackshowstr

	call getstr

	mov si,100+16+7c00h+3	;时间信息端口数地址########	
	mov di,8+7c00h+3	;字符串空间存储地址#########
	mov cx,6

    setclocks:	
	push cx
	
	mov ax,cs:[di]
	sub ah,30h
	sub al,30h
	cmp ah,9
	ja nonumber
	cmp al,9
	ja nonumber

	mov cl,4
	shl ah,cl
	or ah,al

	mov al,cs:[si]
	out 70h,al
	mov al,ah
	out 71h,al
	
	inc si
	add di,3
	
	pop cx
	loop setclocks

	mov bl,0
	call ack

setclockend:
	pop di
	pop si
	pop ax
	pop cx
	ret

  nonumber:
	pop cx
	mov bl,1
	call ack
	jmp setclockend
	

;///显示功能
showchoice:
	push cx
	push ax
	push dx
	push bx

	mov ax,0b800h
	mov es,ax
	
	mov cx,4
	mov bx,40+7c00h+3 	;功能行字符串起始地址###########
	mov dh,0
showchoices0:
	call showstart
	add bx,16
	inc dh
	loop showchoices0
showchoicend:
	pop bx
	pop dx
	pop ax
	pop cx
	ret
	
showstart:		;dh为行  dl为列40   cs:bx为起始位置	
	push bx
	push dx
	push ax
	
	mov dl,0
	mov al,160
	mul dh
	mov di,ax

	add dl,dl
	mov dh,0
	add di,dx
  showstarts:
	cmp byte ptr cs:[bx],0
	je showend
	mov ah,byte ptr cs:[bx]
	mov es:[di],ah
	mov byte ptr es:[di+1],00001001b
	inc bx
	add di,2
	jmp showstarts
  showend:
	pop ax
	pop dx
	pop bx
	ret
	
	
;///读取输入字符串的程序
 getstr: 
	push ax
	push bx
	push cx
			;清空即将输入的地方
	mov ax,0b800h
	mov es,ax
	mov bx,5*160
	mov cx,32
  getstrloop:
	mov byte ptr es:[bx],0
	add bx,2
	loop getstrloop
	
	mov word ptr cs:[6+3+7c00h],0	;清空栈##################

  getstrs:
	mov ah,0
	int 16h
	cmp al,20h	;ascll小于20h 说明不是字符
	jb nochar
	mov ah,0	
	call charstack	;字符入栈
	mov ah,2
	call charstack	;显示栈中的字符
	jmp getstrs

  nochar:
	cmp ah,0eh	;退格键的扫描码
	je backspace
	cmp ah,1ch	;enter 键扫描码
	je enter
	jmp getstrs	;其他键不做处理

  backspace:
	mov ah,1
	call charstack	;字符出栈
	mov ah,2
	call charstack 	;
	jmp getstrs
  
  enter:
	mov al,0
	mov ah,0
	call charstack	;0入栈
	mov ah,2
	call charstack	;显示栈中的字符

	pop cx
	pop bx
	pop ax
	ret


;存储字符串子程序
  charstack:
	jmp charstart

  charstart:
	push bx
	push dx
	push di
	push es
	push cx
	
	cmp ah,2
	ja sret

	mov di,6+7c00h+3	;存放栈顶值的偏移地址#############
	mov si,8+7c00h+3	;存放栈开始的地址##############

	mov bl,ah
	mov bh,0
	add bx,bx
	add bx,3+7c00h		;#################
	jmp word ptr cs:[bx]

  charpush:

	cmp word ptr cs:[di],17		;是否超出存储空间
	je sret
	mov bx,cs:[di]			;bx=栈顶值
	mov cs:[si][bx],al		;al 入栈
	inc word ptr cs:[di]
	jmp sret

  charpop:
	cmp word ptr cs:[di],0	
	je sret
	dec word ptr cs:[di]
	mov al,cs:[si][bx]
	jmp sret
	
  charshow:
	push di
	pop cx		;cx存放栈顶值的偏移地址
	mov bx,0b800h
	mov es,bx
	mov al,160
	mov dh,5	;di为 4 行 0列
	mov dl,0
	mul dh
	mov di,ax
	add dl,dl
	mov dh,0
	add di,dx
	mov bx,0	
  charshows:
	push di		;保存行列地址
	mov di,cx
	cmp bx,cs:[di]
	jne noempty
	pop di
	mov byte ptr es:[di],' '
	jmp sret
  noempty:
	pop di		;di为行列地址
	mov al,cs:[si][bx]
	mov es:[di],al
	mov byte ptr es:[di+1],00000111b
	inc bx
	add di,2
	jmp charshows

  sret:
	pop cx
	pop es
	pop di
	pop dx
	pop bx
	ret

;2号功能 引导现有操作系统
startsys:
	mov ax,0
	mov es,ax
	mov bx,7c00h

	mov al,1	;读取扇区数
	mov ch,0	;磁道号	
	mov cl,1	;扇区号
	mov dl,80h	;驱动器号
	mov dh,0	;磁头号
			;es:bx指向从扇区读入的内存区
	mov ah,2	;ah为功能号 3为写扇区 2为读扇区
	int 13h


	mov word ptr ds:[0],7c00h
	mov word ptr ds:[2],0
	jmp dword ptr ds:[0]	;操作系统起始地址###########

;/ack 回应清空键盘缓冲区 bl为功能号调用不同字符串
ack:
jmp ackstart
 str1: db'set success,press Enter to return',0
 str2: db'set failed:formal error,press Enter to return',0
 str3: db'press Enter to return',0
 adr:dw offset str1-offset mpc+7c00h,offset str2-offset mpc+7c00h,offset str3-offset mpc+7c00h    ;#####
  ackstart:	
	push ax
	push bx
	push cx
	push dx
	push es

	mov bh,0
	add bl,bl
	add bx,offset adr-offset mpc+7c00h  ;########
	mov bx,cs:[bx]

	mov dh,6	;6行0列
	mov dl,0
	call ackshowstr
		


  acknext:		;等待回车
	mov ah,0
	int 16h
	cmp ah,1ch	;为回车键的扫描码
	je  ackend
	jmp acknext

	

  ackend:
				;清空提示4行5行与6行的提示
	mov ax,0b800h
	mov es,ax
	mov bx,4*160
	mov cx,64
  ackloop:
	mov byte ptr es:[bx],0
	add bx,2
	loop ackloop

	mov bx,5*160
	mov cx,32
  ackloop1:
	mov byte ptr es:[bx],0
	mov byte ptr es:[bx+1],00000111b
	add bx,2
	loop ackloop1

	mov bx,6*160
	mov cx,64
  ackloop2:
	mov byte ptr es:[bx],0
	add bx,2
	loop ackloop2


	
	pop es
	pop dx
	pop cx
	pop bx
	pop ax
	ret

;///
ackshowstr:		;cs:bx为字符串起始地址
	push ax
	push bx
	push cx
	push dx
	push es
	push di

	mov ax,0b800h
	mov es,ax
	mov al,160
	mul dh
	mov di,ax
	add dl,dl
	mov dh,0
	add di,dx
  ackstrloop:
	cmp byte ptr cs:[bx],0
	je ackshowstrend
	mov al,cs:[bx]
	mov es:[di],al
	inc bx
	add di,2
	jmp ackstrloop
	
 ackshowstrend:
	pop di
	pop es
	pop dx
	pop cx
	pop bx
	pop ax
	ret

code ends
end start





基本上注释了 所有逻辑,有疑惑的朋友可以加我qq1023499413 探讨

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值