367 lines
6.6 KiB
Markdown
367 lines
6.6 KiB
Markdown
# 实验九:BIOS中断
|
||
|
||
## 一、基础性实验
|
||
|
||
### 1.1 实验目的
|
||
|
||
掌握BIOS中断调用的基本方法,理解BIOS中断在汇编语言程序设计中的作用。
|
||
|
||
### 1.2 实验内容
|
||
|
||
#### 程序 1:显示字符串程序
|
||
|
||
使用BIOS中断在屏幕上显示字符串。
|
||
|
||
```asm
|
||
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中断读取键盘状态。
|
||
|
||
```asm
|
||
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中断读取系统时间。
|
||
|
||
```asm
|
||
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中断产生声音。
|
||
|
||
```asm
|
||
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 思考题
|
||
|
||
1. INT 10H 中断的功能号 13H 表示什么功能?
|
||
2. INT 16H 中断读取键盘返回值的格式是什么?
|
||
3. INT 1AH 中断的 AH=02H 功能返回哪些数据?
|
||
4. 声音程序中如何控制声音的频率?
|
||
|
||
---
|
||
|
||
## 二、加强性实验
|
||
|
||
### 2.1 实验目的
|
||
|
||
掌握BIOS中断的综合应用,实现图形显示、键盘计数和时钟显示等功能。
|
||
|
||
### 2.2 实验内容
|
||
|
||
#### 程序 1:图形显示程序
|
||
|
||
使用BIOS中断在屏幕上绘制图形。
|
||
|
||
```asm
|
||
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中断统计键盘按键次数。
|
||
|
||
```asm
|
||
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中断实时显示系统时间。
|
||
|
||
```asm
|
||
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 思考题
|
||
|
||
1. 图形显示程序中如何切换到图形模式?
|
||
2. 键盘计数器程序中如何检测是否有按键按下?
|
||
3. 时钟显示程序中如何将二进制时间转换为ASCII字符串?
|
||
4. 上述三个程序分别使用了哪些BIOS中断? |