Files
2026-06-25 00:09:09 +08:00

11 KiB
Raw Permalink Blame History

实验九 BIOS中断实验报告

一、实验目的

  1. 掌握BIOS中断调用的基本原理和方法
  2. 学会使用INT 10H进行屏幕显示和图形操作
  3. 学会使用INT 16H进行键盘输入处理
  4. 学会使用INT 1AH读取系统时间和日期
  5. 掌握通过端口操作控制硬件的方法

二、实验内容

2.1 基础性实验

实验1-1字符串显示程序

实验题目使用INT 10H的13H功能显示字符串

程序源码 (string_display.asm)

; 实验九 - 字符串显示程序
; 功能: 使用INT 10H的13H功能在屏幕上显示字符串
; 模式: 文本模式 80x25 彩色

.MODEL SMALL
.DATA
    MSG DB 'Hello, BIOS Interrupt!', 0DH, 0AH, '$'
    CRLF DB 0DH, 0AH, '$'

.CODE
.STARTUP
    MOV AX, @DATA
    MOV DS, AX

    ; 设置光标位置 (0, 0)
    MOV AH, 02H
    MOV BH, 0
    MOV DH, 0
    MOV DL, 0
    INT 10H

    ; 使用INT 10H的13H功能显示字符串
    MOV AH, 13H
    MOV AL, 01H
    MOV BH, 0
    MOV BL, 0FH
    MOV CX, 24
    LEA BP, MSG
    INT 10H

    MOV AH, 01H
    INT 21H
.EXIT
END

说明INT 10H的13H功能用于显示带属性的字符串AL=01H表示字符串包含属性BL中指定前景色。


实验1-2键盘输入程序

实验题目使用INT 16H读取键盘输入

程序源码 (keyboard_input.asm)

; 实验九 - 键盘输入程序
.MODEL SMALL
.DATA
    PROMPT DB 'Please press any key: ', '$'
    KEY_MSG DB 'You pressed: ', '$'
    CRLF DB 0DH, 0AH, '$'
    BUFFER DB 80 DUP(?)

.CODE
.STARTUP
    MOV AX, @DATA
    MOV DS, AX

    LEA DX, PROMPT
    MOV AH, 09H
    INT 21H

    MOV AH, 10H
    INT 16H

    MOV [BUFFER], AL
    MOV [BUFFER+1], AH

    LEA DX, CRLF
    MOV AH, 09H
    INT 21H

    LEA DX, KEY_MSG
    MOV AH, 09H
    INT 21H

    MOV AL, [BUFFER]
    CALL PRINT_CHAR

    MOV AH, 02H
    MOV DL, ' '
    INT 21H

    MOV AL, [BUFFER+1]
    CALL PRINT_HEX

    MOV AH, 00H
    INT 16H
.EXIT

PRINT_CHAR PROC
    PUSH AX
    MOV DL, AL
    MOV AH, 02H
    INT 21H
    POP AX
    RET
PRINT_CHAR ENDP

PRINT_HEX PROC
    PUSH CX
    PUSH DX
    MOV DL, AL
    MOV CL, 4
    SHR DL, CL
    CALL PRINT_NIBBLE
    MOV DL, AL
    AND DL, 0FH
    CALL PRINT_NIBBLE
    POP DX
    POP CX
    RET
PRINT_HEX ENDP

PRINT_NIBBLE PROC
    PUSH DX
    CMP DL, 10
    JB IS_DIGIT
    ADD DL, 'A' - 10
    JMP PRINT_IT
IS_DIGIT:
    ADD DL, '0'
PRINT_IT:
    MOV AH, 02H
    INT 21H
    POP DX
    RET
PRINT_NIBBLE ENDP
END

说明INT 16H的10H功能读取扩展键盘00H功能读取基本键盘返回值AL=ASCII码AH=扫描码。


实验1-3读取时间程序

实验题目使用INT 1AH读取系统时间

程序源码 (read_time.asm)

; 实验九 - 读取时间程序
.MODEL SMALL
.DATA
    TIME_MSG DB 'Current system time: ', '$'
    HOUR_DB '00', ':', '$'
    MIN_DB '00', ':', '$'
    SEC_DB '00', '$'
    CRLF DB 0DH, 0AH, '$'

.CODE
.STARTUP
    MOV AX, @DATA
    MOV DS, AX

MAIN_LOOP:
    MOV AH, 02H
    INT 1AH
    ; DL=日, DH=时, CL=分, CH=秒 (BCD)

    MOV AL, DH
    CALL BIN_TO_BCD
    MOV [HOUR_DB], AH
    MOV [HOUR_DB+1], AL

    MOV AL, CL
    CALL BIN_TO_BCD
    MOV [MIN_DB], AH
    MOV [MIN_DB+1], AL

    MOV AL, CH
    CALL BIN_TO_BCD
    MOV [SEC_DB], AH
    MOV [SEC_DB+1], AL

    MOV AX, 0600H
    MOV BH, 07H
    MOV CX, 0000H
    MOV DX, 184FH
    INT 10H

    MOV AH, 02H
    MOV BH, 0
    MOV DH, 10
    MOV DL, 30
    INT 10H

    LEA DX, TIME_MSG
    MOV AH, 09H
    INT 21H

    LEA DX, HOUR_DB
    MOV AH, 09H
    INT 21H

    LEA DX, MIN_DB
    MOV AH, 09H
    INT 21H

    LEA DX, SEC_DB
    MOV AH, 09H
    INT 21H

    MOV CX, 0
    MOV DX, 0
    MOV AH, 86H
    INT 15H

    JMP MAIN_LOOP
.EXIT

BIN_TO_BCD PROC
    PUSH DX
    MOV AH, 0
    MOV DL, 10
    DIV DL
    MOV DL, AH
    MOV AH, AL
    MOV AL, DL
    POP DX
    RET
BIN_TO_BCD ENDP
END

说明INT 1AH的02H功能返回BCD格式时间需要转换为ASCII字符串显示。


实验1-4声音程序

实验题目:通过端口操作产生声音

程序源码 (sound_porgram.asm)

; 实验九 - 声音程序
.MODEL SMALL
.DATA
    TONE_DB 200, 400, 600, 800, 1000
    COUNT DB 5

.CODE
.STARTUP
    MOV AX, @DATA
    MOV DS, AX

    MOV AL, 10110110B
    OUT 43H, AL

    LEA SI, TONE_DB
    MOV CL, [COUNT]

TONE_LOOP:
    LODSB
    CBW

    OUT 42H, AL
    MOV AL, AH
    OUT 42H, AL

    IN AL, 61H
    OR AL, 00000011B
    OUT 61H, AL

    MOV CX, 0FFFFH
DELAY1:
    LOOP DELAY1

    IN AL, 61H
    AND AL, 11111100B
    OUT 61H, AL

    MOV CX, 0FFFFH
DELAY2:
    LOOP DELAY2

    DEC CL
    JNZ TONE_LOOP

    MOV AH, 01H
    INT 21H
.EXIT
END

说明通过端口61H控制扬声器端口42H设置8253计数器2的频率。频率=1193180/计数值。


2.2 加强性实验

实验2-1图形显示程序

实验题目:设置图形模式并画线

程序源码 (graphics_display.asm)

; 实验九 - 图形显示程序
.MODEL SMALL
.DATA
    MSG DB 'Press any key to exit...', '$'

.CODE
.STARTUP
    MOV AH, 00H
    MOV AL, 13H
    INT 10H

    ; 红色水平线
    MOV CX, 20
    MOV DX, 50
LINE1:
    MOV AL, 0FCH
    MOV AH, 0CH
    INT 10H
    INC CX
    CMP CX, 100
    JNE LINE1

    ; 绿色垂直线
    MOV CX, 150
    MOV DX, 30
LINE2:
    MOV AL, 3FH
    MOV AH, 0CH
    INT 10H
    INC DX
    CMP DX, 90
    JNE LINE2

    ; 蓝色斜线
    MOV CX, 200
    MOV DX, 100
LINE3:
    MOV AL, 9FH
    MOV AH, 0CH
    INT 10H
    INC CX
    INC DX
    CMP CX, 260
    JNE LINE3

    MOV AH, 00H
    MOV AL, 03H
    INT 10H

    LEA DX, MSG
    MOV AH, 09H
    INT 21H

    MOV AH, 00H
    INT 16H
.EXIT
END

说明INT 10H的00H功能设置图形模式13H(320x200x256色)0CH功能在图形模式下画点。


实验2-2键盘计数器程序

实验题目:统计按键次数

程序源码 (keyboard_counter.asm)

; 实验九 - 键盘计数器程序
.MODEL SMALL
.DATA
    TITLE_MSG DB '=== Keyboard Counter ===', 0DH, 0AH, '$'
    COUNT_MSG DB 'Key presses: ', '$'
    COUNT_STR DB '00000', '$'

.CODE
.STARTUP
    MOV AX, @DATA
    MOV DS, AX

    MOV AX, 0600H
    MOV BH, 07H
    MOV CX, 0000H
    MOV DX, 184FH
    INT 10H

    LEA DX, TITLE_MSG
    MOV AH, 09H
    INT 21H

    LEA DX, COUNT_MSG
    MOV AH, 09H
    INT 21H

    LEA DX, COUNT_STR
    MOV AH, 09H
    INT 21H

    XOR CX, CX

COUNT_LOOP:
    MOV AH, 01H
    INT 16H
    JZ NO_KEY

    MOV AH, 00H
    INT 16H

    CMP AH, 01H
    JE EXIT_PROGRAM

    INC CX
    CALL WORD_TO_STR

    MOV AH, 02H
    MOV BH, 0
    MOV DH, 2
    MOV DL, 12
    INT 10H

    LEA DX, COUNT_STR
    MOV AH, 09H
    INT 21H

NO_KEY:
    MOV CX, 0FFFFH
DELAY:
    LOOP DELAY
    JMP COUNT_LOOP

EXIT_PROGRAM:
.EXIT

WORD_TO_STR PROC
    PUSH AX
    PUSH BX
    PUSH DX
    MOV AX, CX
    MOV BX, 10
    MOV DX, 0
    DIV BX
    ADD DL, '0'
    MOV [COUNT_STR+4], DL
    MOV DX, 0
    DIV BX
    ADD DL, '0'
    MOV [COUNT_STR+3], DL
    MOV DX, 0
    DIV BX
    ADD DL, '0'
    MOV [COUNT_STR+2], DL
    MOV DX, 0
    DIV BX
    ADD DL, '0'
    MOV [COUNT_STR+1], DL
    MOV DX, 0
    DIV BX
    ADD DL, '0'
    MOV [COUNT_STR], DL
    POP DX
    POP BX
    POP AX
    RET
WORD_TO_STR ENDP
END

说明INT 16H的01H功能检查是否有按键(ZF=1表示无按键)00H功能读取按键。


实验2-3时钟显示程序

实验题目:实时显示系统时间

程序源码 (clock_display.asm)

; 实验九 - 时钟显示程序
.MODEL SMALL
.DATA
    TIME_FORMAT DB '00:00:00', '$'
    TITLE DB '=== Real Time Clock ===', 0DH, 0AH, '$'
    DATE_FMT DB 'Date: 20XX/XX/XX', '$'

.CODE
.STARTUP
    MOV AX, @DATA
    MOV DS, AX

MAIN_LOOP:
    MOV AH, 02H
    INT 1AH

    MOV AL, DH
    CALL BCD_TO_STR
    MOV [TIME_FORMAT], AH
    MOV [TIME_FORMAT+1], AL

    MOV AL, CL
    CALL BCD_TO_STR
    MOV [TIME_FORMAT+3], AH
    MOV [TIME_FORMAT+4], AL

    MOV AL, CH
    CALL BCD_TO_STR
    MOV [TIME_FORMAT+6], AH
    MOV [TIME_FORMAT+7], AL

    MOV AH, 04H
    INT 1AH

    MOV AL, CH
    CALL BCD_TO_STR
    MOV [DATE_FMT+8], AH
    MOV [DATE_FMT+9], AL

    MOV AL, CL
    CALL BCD_TO_STR
    MOV [DATE_FMT+12], AH
    MOV [DATE_FMT+13], AL

    MOV AL, DH
    CALL BCD_TO_STR
    MOV [DATE_FMT+15], AH
    MOV [DATE_FMT+16], AL

    MOV AL, DL
    CALL BCD_TO_STR
    MOV [DATE_FMT+18], AH
    MOV [DATE_FMT+19], AL

    MOV AX, 0600H
    MOV BH, 07H
    MOV CX, 0000H
    MOV DX, 184FH
    INT 10H

    MOV AH, 02H
    MOV BH, 0
    MOV DH, 10
    MOV DL, 35
    INT 10H

    LEA DX, TITLE
    MOV AH, 09H
    INT 21H

    MOV AH, 02H
    MOV BH, 0
    MOV DH, 12
    MOV DL, 35
    INT 10H

    LEA DX, TIME_FORMAT
    MOV AH, 09H
    INT 21H

    MOV AH, 02H
    MOV BH, 0
    MOV DH, 14
    MOV DL, 32
    INT 10H

    LEA DX, DATE_FMT
    MOV AH, 09H
    INT 21H

    MOV CX, 0
    MOV DX, 0
    MOV AH, 86H
    INT 15H

    MOV AH, 01H
    INT 16H
    JZ MAIN_LOOP

    MOV AH, 00H
    INT 16H
    CMP AH, 01H
    JNE MAIN_LOOP
.EXIT

BCD_TO_STR PROC
    PUSH DX
    MOV AH, AL
    AND AH, 0F0H
    MOV DL, 4
    SHR AH, DL
    ADD AH, '0'
    MOV DL, AL
    AND DL, 0FH
    ADD DL, '0'
    MOV AL, DL
    POP DX
    RET
BCD_TO_STR ENDP
END

说明INT 1AH的02H读取BCD时间04H读取BCD日期。BCD转ASCII需要分离高低4位并加上'0'。


三、思考题

3.1 图形显示程序中如何切换到图形模式?

通过INT 10H的00H功能设置显示模式

MOV AH, 00H
MOV AL, 13H  ; 320x200x256色图形模式
INT 10H

切回文本模式AL=03H

3.2 键盘计数器程序中如何检测是否有按键按下?

使用INT 16H的01H功能

MOV AH, 01H
INT 16H
JZ NO_KEY  ; ZF=1表示无按键

ZF=0表示有按键可用。

3.3 时钟显示程序中如何将二进制时间转换为ASCII字符串

BIOS返回的是BCD码需分离高低4位并加上ASCII'0'

MOV AH, AL
AND AH, 0F0H  ; 取高位
SHR AH, 4
ADD AH, '0'
MOV DL, AL
AND DL, 0FH  ; 取低位
ADD DL, '0'

3.4 上述三个程序分别使用了哪些BIOS中断

程序 使用的中断
图形显示程序 INT 10H (00H设置模式, 0CH画点), INT 16H (00H读取按键)
键盘计数器程序 INT 10H (02H光标, 13H显示), INT 16H (01H检查, 00H读取)
时钟显示程序 INT 10H (00H清除, 02H光标, 09H显示), INT 1AH (02H时间, 04H日期), INT 15H (86H延时), INT 16H (01H检查, 00H读取)

四、文件清单

文件名 功能描述
string_display.asm 字符串显示程序 - 使用INT 10H的13H功能
keyboard_input.asm 键盘输入程序 - 使用INT 16H
read_time.asm 读取时间程序 - 使用INT 1AH
sound_porgram.asm 声音程序 - 通过端口61H/42H控制扬声器
graphics_display.asm 图形显示程序 - 图形模式13H画线
keyboard_counter.asm 键盘计数器程序 - 统计按键次数
clock_display.asm 时钟显示程序 - 实时显示系统时间
REPORT.md 本实验报告