6.6 KiB
6.6 KiB
实验九:BIOS中断
一、基础性实验
1.1 实验目的
掌握BIOS中断调用的基本方法,理解BIOS中断在汇编语言程序设计中的作用。
1.2 实验内容
程序 1:显示字符串程序
使用BIOS中断在屏幕上显示字符串。
DATAS SEGMENT
MSG DB 'Hello, BIOS!', 0
LEN EQU $-MSG
DATAS ENDS
CODES SEGMENT
ASSUME CS:CODES, DS:DATAS
START:
MOV AX, DATAS
MOV DS, AX
MOV AH, 13H
MOV AL, 01H
MOV BH, 00H
MOV BL, 07H
LEA BP, MSG
MOV CX, LEN
INT 10H
MOV AH, 4CH
INT 21H
CODES ENDS
END START
程序说明:
- INT 10H 是 BIOS 显示服务中断
- AH=13H 表示写字符串功能
- AL=01H 表示字符串包含显示属性
- BH=00H 表示显示页码
- BL=07H 表示白字黑底属性
- CX=LEN 表示字符串长度
- DS:BP 指向字符串地址
程序 2:键盘输入程序
使用BIOS中断读取键盘状态。
CODES SEGMENT
ASSUME CS:CODES
START:
MOV AH, 00H
INT 16H
MOV AH, 0EH
INT 10H
CMP AL, 1BH
JNE START
MOV AH, 4CH
INT 21H
CODES ENDS
END START
程序说明:
- INT 16H 是 BIOS 键盘服务中断
- AH=00H 表示读取键盘输入
- 返回值:AH=扫描码,AL=ASCII码
- AH=0EH,INT 10H 表示电传打字机功能(显示字符)
程序 3:读取时间程序
使用BIOS中断读取系统时间。
CODES SEGMENT
ASSUME CS:CODES
START:
MOV AH, 02H
INT 1AH
MOV AL, DH
CALL DISP_BYTE
MOV DL, ':'
MOV AH, 02H
INT 21H
MOV AL, CL
CALL DISP_BYTE
MOV AH, 4CH
INT 21H
DISP_BYTE PROC
PUSH CX
MOV AH, 0
MOV CL, 4
SHR AL, CL
ADD AL, 30H
CMP AL, 3AH
JB DISP1
ADD AL, 07H
DISP1:
MOV DL, AL
MOV AH, 02H
INT 21H
POP CX
MOV AL, 0FH
AND AL, CL
ADD AL, 30H
CMP AL, 3AH
JB DISP2
ADD AL, 07H
DISP2:
MOV DL, AL
MOV AH, 02H
INT 21H
RET
DISP_BYTE ENDP
CODES ENDS
END START
程序说明:
- INT 1AH 是 BIOS 时钟服务中断
- AH=02H 表示读取RTC时间
- 返回值:CH=小时,CL=分钟,DH=秒
程序 4:声音程序
使用BIOS中断产生声音。
CODES SEGMENT
ASSUME CS:CODES
START:
MOV AL, 0B6H
OUT 43H, AL
MOV AX, 2000H
OUT 42H, AL
MOV AL, AH
OUT 42H, AL
IN AL, 61H
OR AL, 03H
OUT 61H, AL
MOV CX, 0FFFFH
DELAY:
LOOP DELAY
IN AL, 61H
AND AL, 0FCH
OUT 61H, AL
MOV AH, 4CH
INT 21H
CODES ENDS
END START
程序说明:
- 通过端口操作编程8253定时器
- 43H 为控制端口,42H 为计数器端口,61H 为扬声器控制端口
- 首先设置定时器模式,然后写入计数值
- 最后打开扬声器并延时
1.3 实验结果
程序运行后,显示字符串程序在屏幕上显示"Hello, BIOS!"字符串;键盘输入程序等待键盘输入并回显;读取时间程序在屏幕上显示当前系统时间;声音程序使PC喇叭发出声音。
1.4 思考题
- INT 10H 中断的功能号 13H 表示什么功能?
- INT 16H 中断读取键盘返回值的格式是什么?
- INT 1AH 中断的 AH=02H 功能返回哪些数据?
- 声音程序中如何控制声音的频率?
二、加强性实验
2.1 实验目的
掌握BIOS中断的综合应用,实现图形显示、键盘计数和时钟显示等功能。
2.2 实验内容
程序 1:图形显示程序
使用BIOS中断在屏幕上绘制图形。
CODES SEGMENT
ASSUME CS:CODES
START:
MOV AH, 00H
MOV AL, 13H
INT 10H
MOV CX, 100
MOV DX, 100
NEXT_LINE:
MOV AL, 0CH
MOV AH, 0CH
INT 10H
INC CX
CMP CX, 200
JNE NEXT_LINE
MOV CX, 100
INC DX
CMP DX, 150
JNE NEXT_LINE
MOV AH, 00H
INT 16H
MOV AH, 00H
MOV AL, 03H
INT 10H
MOV AH, 4CH
INT 21H
CODES ENDS
END START
程序说明:
- AH=00H, AL=13H 设置 320x200 256色图形模式
- AH=0CH 是画点功能
- AL=0CH 设置颜色值
- CX=列,DX=行
- 程序在屏幕上画一条斜线
程序 2:键盘计数器程序
使用BIOS中断统计键盘按键次数。
DATAS SEGMENT
COUNT DB 0
MSG DB 'Key presses: $'
DATAS ENDS
CODES SEGMENT
ASSUME CS:CODES, DS:DATAS
START:
MOV AX, DATAS
MOV DS, AX
LOOP1:
MOV AH, 01H
INT 16H
JZ NO_KEY
MOV AH, 00H
INT 16H
INC COUNT
CMP COUNT, 100
JAE DONE
JMP LOOP1
NO_KEY:
LEA DX, MSG
MOV AH, 09H
INT 21H
MOV AL, COUNT
CALL DISP_BYTE
MOV AH, 02H
MOV DL, 0DH
INT 21H
MOV DL, 0AH
INT 21H
CMP COUNT, 100
JB LOOP1
DONE:
MOV AH, 4CH
INT 21H
DISP_BYTE PROC
PUSH AX
MOV AH, 0
MOV CL, 4
SHR AL, CL
ADD AL, 30H
MOV DL, AL
MOV AH, 02H
INT 21H
POP AX
MOV AL, 0FH
AND AL, AH
ADD AL, 30H
MOV DL, AL
MOV AH, 02H
INT 21H
RET
DISP_BYTE ENDP
CODES ENDS
END START
程序说明:
- INT 16H 的 AH=01H 功能检查是否有键盘输入
- 如果有按键(ZF=0),则调用 AH=00H 读取按键并计数
- 如果没有按键(ZF=1),则显示当前计数
- 计数达到100时退出程序
程序 3:时钟显示程序
使用BIOS中断实时显示系统时间。
DATAS SEGMENT
TIME_STR DB '00:00:00', 0DH, 0AH, '$'
DATAS ENDS
CODES SEGMENT
ASSUME CS:CODES, DS:DATAS
START:
MOV AX, DATAS
MOV DS, AX
DISPLAY_LOOP:
MOV AH, 02H
INT 1AH
MOV AL, CH
CALL BIN_TO_ASCII
MOV DI, OFFSET TIME_STR
MOV [DI], AX
MOV AL, CL
CALL BIN_TO_ASCII
MOV [DI+3], AX
MOV AL, DH
CALL BIN_TO_ASCII
MOV [DI+6], AX
LEA DX, TIME_STR
MOV AH, 09H
INT 21H
MOV CX, 0FFFFH
DELAY:
LOOP DELAY
JMP DISPLAY_LOOP
BIN_TO_ASCII PROC
PUSH CX
MOV AH, 0
MOV CL, 4
SHR AL, CL
ADD AL, 30H
MOV AH, AL
POP CX
MOV AL, 0FH
AND AL, AH
ADD AL, 30H
RET
BIN_TO_ASCII ENDP
CODES ENDS
END START
程序说明:
- INT 1AH 的 AH=02H 读取实时时钟
- CH=小时,CL=分钟,DH=秒
- BIN_TO_ASCII 过程将二进制数转换为ASCII码
- 程序循环显示时间,每秒更新一次
2.3 实验结果
程序运行后,图形显示程序在屏幕上绘制一条斜线;键盘计数器程序统计键盘按键次数并实时显示;时钟显示程序在屏幕上实时显示当前系统时间。
2.4 思考题
- 图形显示程序中如何切换到图形模式?
- 键盘计数器程序中如何检测是否有按键按下?
- 时钟显示程序中如何将二进制时间转换为ASCII字符串?
- 上述三个程序分别使用了哪些BIOS中断?