前文
[085][汇编语言]课程设计2 :(1)从软盘启动,开机后主界面,列出选项
https://www.jianshu.com/p/0a99d34113c0
课程设计2 :(2)从软盘启动,功能化选项按键 "1"(测试版)
- 新增 : 开机进入主界面后,对按键 “1” 的 功能测试
1、全屏字母小 "a " 代替全屏 空格 " ",测试 [清屏] 功能;
2、在主界面,按下 按键1,进入测试版的功能选项 1) ,屏幕中间出现一个彩色的字母 t ;
3、按下 F1 键,可以再次 [返回] 到主界面;
- 这个测试版最大的突破在于, 在主界面需要通过 按键1 才能进入功能选项,在功能选项页面需要按下 F1键 才能返回到主界面;
测试运行
修改 任务程序 task 部分
;--------------------------------------------------------------
; 任务程序 开始
; 任务程序 从 标号 task 开始 到 标号 taskend 结束
;--------------------------------------------------------------
task: jmp short taskstart
menu_1 db '1) reset pc',0
menu_2 db '2) start system',0
menu_3 db '3) clock',0
menu_4 db '4) set clock',0
menu_address dw offset menu_1 - offset task + 7E00H
dw offset menu_2 - offset task + 7E00H
dw offset menu_3 - offset task + 7E00H
dw offset menu_4 - offset task + 7E00H
;stack db 50 dup(0)
taskstart:
call init_reg
call clear_screen
call toppage
jmp short key_toppage
mov ax,4c00h
int 21H
;--------------------------------------------------------------
; 选项控制: key_toppage
; 功能: 针对首页 toppage 的键盘操作
; 实现: 使用 BIOS int 16h 0号功能,读取一个键盘输入
; 返回值 (ah) = 扫描码 , (al) = ASCII码
; 键 1 2 3 4
; 扫描码 02 03 04 05
;--------------------------------------------------------------
key_toppage: mov ah,0
int 16h
key_input: cmp ah,02H
je key1
cmp ah,03h
je key2
cmp ah,04h
je key3
cmp ah,05h
je key4
; 本意是,这时候读取的输入,如果不是1234就忽略,再读取一个
jmp short key_input
key1: call test1
jmp short taskstart
key2:
key3:
key4:
;--------------------------------------------------------------
test1: call clear_screen
mov di,160*12+40*2
mov al,03H
mov byte ptr es:[di],'t'
mov byte ptr es:[di+1],al
mywait: mov ah,0
int 16H
cmp ah,3BH ; 3BH : F1键扫描码
je ok
jmp short mywait
ok: ret
;--------------------------------------------------------------
; 子程序: toppage
; 功能: 在首页列出4个选项
;--------------------------------------------------------------
toppage: push bx
push di
push cx
push ax
push ds
push es
push si
mov bx, offset menu_address - offset task + 7E00H
mov di,160*8+25*2
mov cx,4 ; 主页显示 4行 功能选项
mov ax,0
mov ds,ax
mov ax,0B800H
mov es,ax
showtoppage: mov si,ds:[bx]
call oneline
add bx,2
add di,160
loop showtoppage
pop si
pop es
pop ds
pop ax
pop cx
pop di
pop bx
ret
oneline: push cx
push di
push si
onelines: mov cl,ds:[si]
mov ch,0
jcxz onelineok
mov byte ptr es:[di],cl
mov ch,02H
mov byte ptr es:[di+1],ch
inc si
add di,2
jmp short onelines
onelineok: pop si
pop di
pop cx
ret
;--------------------------------------------------------------
;--------------------------------------------------------------
; 常用子程序集合 开始
;--------------------------------------------------------------
; 子程序: clear_screen
; 功能: 清屏,将显存中当前屏幕中的字符设为空格符
;--------------------------------------------------------------
clear_screen: push bx
push cx
push es
push ax
mov bx,0B800H
mov es,bx
mov bx,0
mov cx,2000
mov ah,'a'
mov al,00000111B ;黑底白字
clear_screens: mov byte ptr es:[bx],ah
mov byte ptr es:[bx+1],al
add bx,2
loop clear_screens
pop ax
pop es
pop cx
pop bx
ret
;--------------------------------------------------------------
; 子程序:init_reg
; 功能: 寄存器设置
;--------------------------------------------------------------
init_reg: mov ax,0
mov ds,ax
mov ax,0B800H
mov es,ax
ret
;--------------------------------------------------------------
;--------------------------------------------------------------
; 常用子程序集合 结束
;--------------------------------------------------------------
taskend: nop
;--------------------------------------------------------------
; 任务程序结束
;--------------------------------------------------------------
完整源码
- 引导程序 bootcode.asm 不需要改动 直接复制于
- 任务程序 taskcode.asm
assume cs:code
data segment
db 512 dup (0)
data ends
code segment
start:
call setup
call write
mov ax,4c00h
int 21H
setup:
; 任务程序 安装步骤
; 将任务程序机器码安装到data段开辟的内存空间
mov ax,cs
mov ds,ax
mov si, offset task
mov ax,data
mov es,ax
mov di,0
mov cx,offset taskend - offset task
cld
rep movsb
ret
write:
; 利用 int 13H 中断
; 将内存 data 处的任务程序
; 写入 软盘A 0面 0道 2扇区
mov ax,data
mov es,ax
mov bx,0
mov al,1
mov ch,0
mov cl,2
mov dl,0
mov dh,0
mov ah,3
int 13h
ret
;--------------------------------------------------------------
; 任务程序 开始
; 任务程序 从 标号 task 开始 到 标号 taskend 结束
;--------------------------------------------------------------
task: jmp short taskstart
menu_1 db '1) reset pc',0
menu_2 db '2) start system',0
menu_3 db '3) clock',0
menu_4 db '4) set clock',0
menu_address dw offset menu_1 - offset task + 7E00H
dw offset menu_2 - offset task + 7E00H
dw offset menu_3 - offset task + 7E00H
dw offset menu_4 - offset task + 7E00H
;stack db 50 dup(0)
taskstart:
call init_reg
call clear_screen
call toppage
jmp short key_toppage
mov ax,4c00h
int 21H
;--------------------------------------------------------------
; 选项控制: key_toppage
; 功能: 针对首页 toppage 的键盘操作
; 实现: 使用 BIOS int 16h 0号功能,读取一个键盘输入
; 返回值 (ah) = 扫描码 , (al) = ASCII码
; 键 1 2 3 4
; 扫描码 02 03 04 05
;--------------------------------------------------------------
key_toppage: mov ah,0
int 16h
key_input: cmp ah,02H
je key1
cmp ah,03h
je key2
cmp ah,04h
je key3
cmp ah,05h
je key4
; 本意是,这时候读取的输入,如果不是1234就忽略,再读取一个
jmp short key_input
key1: call test1
jmp short taskstart
key2:
key3:
key4:
;--------------------------------------------------------------
test1: call clear_screen
mov di,160*12+40*2
mov al,03H
mov byte ptr es:[di],'t'
mov byte ptr es:[di+1],al
mywait: mov ah,0
int 16H
cmp ah,3BH ; 3BH : F1键扫描码
je ok
jmp short mywait
ok: ret
;--------------------------------------------------------------
; 子程序: toppage
; 功能: 在首页列出4个选项
;--------------------------------------------------------------
toppage: push bx
push di
push cx
push ax
push ds
push es
push si
mov bx, offset menu_address - offset task + 7E00H
mov di,160*8+25*2
mov cx,4 ; 主页显示 4行 功能选项
mov ax,0
mov ds,ax
mov ax,0B800H
mov es,ax
showtoppage: mov si,ds:[bx]
call oneline
add bx,2
add di,160
loop showtoppage
pop si
pop es
pop ds
pop ax
pop cx
pop di
pop bx
ret
oneline: push cx
push di
push si
onelines: mov cl,ds:[si]
mov ch,0
jcxz onelineok
mov byte ptr es:[di],cl
mov ch,02H
mov byte ptr es:[di+1],ch
inc si
add di,2
jmp short onelines
onelineok: pop si
pop di
pop cx
ret
;--------------------------------------------------------------
;--------------------------------------------------------------
; 常用子程序集合 开始
;--------------------------------------------------------------
; 子程序: clear_screen
; 功能: 清屏,将显存中当前屏幕中的字符设为空格符
;--------------------------------------------------------------
clear_screen: push bx
push cx
push es
push ax
mov bx,0B800H
mov es,bx
mov bx,0
mov cx,2000
mov ah,'a'
mov al,00000111B ;黑底白字
clear_screens: mov byte ptr es:[bx],ah
mov byte ptr es:[bx+1],al
add bx,2
loop clear_screens
pop ax
pop es
pop cx
pop bx
ret
;--------------------------------------------------------------
; 子程序:init_reg
; 功能: 寄存器设置
;--------------------------------------------------------------
init_reg: mov ax,0
mov ds,ax
mov ax,0B800H
mov es,ax
ret
;--------------------------------------------------------------
;--------------------------------------------------------------
; 常用子程序集合 结束
;--------------------------------------------------------------
taskend: nop
;--------------------------------------------------------------
; 任务程序结束
;--------------------------------------------------------------
code ends
end start
代码说明
关于测试版的功能选项 1)
test1: call clear_screen
mov di,160*12+40*2
mov al,03H
mov byte ptr es:[di],'t'
mov byte ptr es:[di+1],al
mywait: mov ah,0
int 16H
cmp ah,3BH ; 3BH : F1键扫描码
je ok
jmp short mywait
ok: ret
- 目前测试版的选项功能就是,在屏幕中间显示一个彩色的
字母 t
,之后需要按下指定的返回键(F1键)才可以回到主界面; - 实现的核心是利用
BIOS int 16H
中断,只有读到指定的返回键 - F1键
才会实现跳转; -
返回键 ,当然可以设置成其他键,只要在
cmp ah,3BH
这里填上相应的扫描码即可;
代码参考
- 这位博主的答案给我帮助很大!