《汇编语言(第四版)》 . 王爽著 . 清华大学出版社 . 2019
实验 13 编写、应用中断例程
一些例程与检测点
使用 int 指令调用中断处理程序
可以在程序中使用 int 指令调用任何一个中断的中断处理程序
在下面的程序中,CPU 执行 int 0
指令时,将引发中断过程,执行 0 号中断处理程序
1 2 3 4 5 6 7 8 9 10 11 assume cs :codecode segment start: mov ax ,0b800h mov es ,ax mov byte ptr es :[12 *160 +40 *2 ],'!' int 0 code ends end start
测试程序运行
编写、安装中断 7ch 的中断例程(1)
1 2 3 4 5 6 7 8 9 10 11 12 13 assume cs :codecode segment start: mov ax ,3456 int 7ch add ax ,ax adc dx ,dx mov ax ,4c00h int 21h code ends end start
需要做的工作:
编写实现求平方功能的程序;
安装程序,将其安装在 0:200 处;
设置中断向量表,将程序的入口地址保存在 7ch 表项中,使其成为中断 7ch 的中断例程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 assume cs :codecode segment start: mov ax ,cs mov ds ,ax mov si ,offset sqr mov ax ,0 mov es ,ax mov di ,0200h mov cx ,offset sqrend-offset sqr cld rep movsb mov ax ,0 mov es ,ax mov word ptr es :[7ch *4 ],200h mov word ptr es :[7ch *4 +2 ],0 mov ax ,4c00h int 21h sqr: mul ax iret sqrend: nop code ends end start
在执行完中断例程后,应该用 iret 指令恢复 int 7ch 执行前的标志寄存器和 CS、IP 的值
int 指令和 iret 指令的配合使用与 call 指令和 ret 指令的配合使用具有相似的思路
用 Debug 跟踪程序运行
编写、安装中断 7ch 的中断例程(2)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 assume cs :codedata segment db 'conversation' ,0 data ends code segment start: mov ax ,data mov ds ,ax mov si ,0 int 7ch mov ax ,4c00h int 21h code ends end start
安装程序如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 assume cs :codecode segment start: mov ax ,cs mov ds ,ax mov si ,offset capital mov ax ,0 mov es ,ax mov di ,0200h mov cx ,offset capitalend-offset capital cld rep movsb mov ax ,0 mov es ,ax mov word ptr es :[7ch *4 ],200h mov word ptr es :[7ch *4 +2 ],0 mov ax ,4c00h int 21h capital: push cx push si change: mov cl ,ds :[si ] mov ch ,0 jcxz ok and byte ptr [si ],11011111b inc si jmp short change ok: pop si pop cx iret capitalend: nop code ends end start
用 Debug 跟踪程序运行
安装中断例程的程序的基本框架
1)主程序
串传送操作:
设置 ds:si 指向源地址
设置 es:di 指向目的地址
设置 cx 为传输长度
设置传输方向
进行串传送
设置中断向量表:
将中断例程的入口地址写入相应表项
程序返回;
2)子程序
中断处理函数:
保存用到的寄存器
处理中断
恢复用到的寄存器
用 iret 指令返回
用 7ch 中断例程完成 loop 指令的功能
loop s 的执行需要两个信息,循环次数和到 s 的位移,7ch 中断例程也需要以这两个变量为参数,用 cx 存放循环次数,用 bx 存放位移。
应用举例:在屏幕中间显示 80 个 “!”。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 assume cs :codecode segment start: mov ax ,0b800h mov es ,ax mov di ,160 *12 mov bx ,offset s-offset se mov cx ,80 s: mov byte ptr es :[di ],'!' add di ,2 int 7ch se: nop mov ax ,4c00h int 21h code ends end start
为了模拟 loop 指令,7ch 中断例程应具备下面的功能:
dec cx;
如果 (cx)≠0,转到标号 s 处执行,否则向下执行。
通过 se 的偏移地址加上 bx 中存放的转移位移得到 s 的偏移地址
通过改变栈中被压栈的 IP 的内容,再使用 iret 指令,从而真正改变 IP,使 CS:IP 转移到标号 s 处
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 assume cs :codecode segment start: mov ax ,cs mov ds ,ax mov si ,offset lp mov ax ,0 mov es ,ax mov di ,0200h mov cx ,offset lpend-offset lp cld rep movsb mov ax ,0 mov es ,ax mov word ptr es :[7ch *4 ],200h mov word ptr es :[7ch *4 +2 ],0 mov ax ,4c00h int 21h lp: push bp mov bp ,sp dec cx jcxz lpret add [bp +2 ],bx lpret: pop bp iret lpend: nop code ends end start
测试程序运行
检测点 13.1
(1)-32768~32767
实际上 loop 指令为短转移,对 IP 的修改范围为 -128 ~ 127
(2)应用程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 assume cs :codedata segment db 'conversation' ,0 data ends code segment start: mov ax ,data mov ds ,ax mov si ,0 mov ax ,0b800h mov es ,ax mov di ,12 *160 s: cmp byte ptr [si ],0 je ok mov al ,[si ] mov es :[di ],al inc si add di ,2 mov bx ,offset s-offset ok int 7ch ok: mov ax ,4c00h int 21h code ends end start
安装程序如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 assume cs :codecode segment start: mov ax ,cs mov ds ,ax mov si ,offset print mov ax ,0 mov es ,ax mov di ,0200h mov cx ,offset printend-offset print cld rep movsb mov ax ,0 mov es ,ax mov word ptr es :[7ch *4 ],200h mov word ptr es :[7ch *4 +2 ],0 mov ax ,4c00h int 21h print: push bp mov bp ,sp add [bp +2 ],bx pop bp iret printend: nop code ends end start
测试程序运行
检测点 13.2
(1)错误,内存区域只读。
(2)int 19h 在 DOS 启用之前调用,由 BIOS 提供。
编程:在屏幕的 5 行 12 列显示 3 个红底高亮闪烁绿色的 “a”
BIOS 中断例程应用
BIOS 和 DOS 提供的中断例程,用 ah 来传递内部子程序的编号。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 assume cs :codecode segment mov ah ,2 mov bh ,0 mov dh ,5 mov dl ,12 int 10h mov ah ,9 mov al ,'a' mov bl ,11001010b mov bh ,0 mov cx ,3 int 10h mov ax ,4c00h int 21h code ends end
测试程序运行
编程:在屏幕的 5 行 12 列显示字符串 “Welcome to masm!”
DOS 中断例程应用
DOS 为程序员提供了许多可以调用的子程序,都包含在 int 21h 中断例程中
int 21h 中断例程的 4ch 号功能,即程序返回功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 assume cs :codedata segment db 'Welcome to masm' ,'$' data ends code segment start: mov ah ,2 mov bh ,0 mov dh ,5 mov dl ,12 int 10h mov ax ,data mov ds ,ax mov dx ,0 mov ah ,9 int 21h mov ax ,4c00h int 21h code ends end start
测试程序运行
实验任务
实验任务(1)(2)在之前的程序中都有所体现,这里只将没有与之前完全重复的实验任务(1)再做一遍
实验任务(1)
应用程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 assume cs :codedata segment db "welcome to masm! " ,0 data ends code segment start: mov dh ,10 mov dl ,10 mov cl ,2 mov ax ,data mov ds ,ax mov si ,0 int 7ch mov ax ,4c00h int 21h code ends end start
编写程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 assume cs :codecode segment start: mov ax ,cs mov ds ,ax mov si ,offset print mov ax ,0 mov es ,ax mov di ,0200h mov cx ,offset printend-offset print cld rep movsb mov ax ,0 mov es ,ax mov word ptr es :[7ch *4 ],200h mov word ptr es :[7ch *4 +2 ],0 mov ax ,4c00h int 21h print: push ax push bx push cx push dx push si push di push es mov bl ,dl mov bh ,0 add bx ,bx mov al ,dh mov ah ,160 mul ah mov di ,ax mov ax ,0b800h mov es ,ax mov ah ,2 s: mov al ,ds :[si ] cmp byte ptr ds :[si ],0 je ok mov es :[di +bx ],ax inc si add bx ,2 jmp short s ok: pop es pop di pop si pop dx pop cx pop bx pop ax iret printend: nop code ends end start
测试程序运行
实验任务(2)
见上文 用 7ch 中断例程完成 loop 指令的功能
实验任务(3)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 assume cs :codecode segment s1: db 'Good,better,best,' ,'$' s2: db 'Never let it rest,' ,'$' s3: db 'Till good is better,' ,'$' s4: db 'And better,best.' ,'$' s : dw offset s1,offset s2,offset s3,offset s4 row: db 2 ,4 ,6 ,8 start: mov ax ,cs mov ds ,ax mov bx ,offset s mov si ,offset row mov cx ,4 ok: mov bh ,0 mov dh ,ds :[si ] mov dl ,0 mov ah ,2 int 10h mov dx ,ds :[bx ] mov ah ,9 int 21h inc si add bx ,2 loop ok mov ax ,4c00h int 21h code ends end start
测试程序运行
汇编语言实验合集
汇编语言实验合集
实验 1 查看 CPU 和内存,用机器指令和汇编指令编程
实验 2 用机器指令和汇编指令编程
实验 3 编程、编译、连接、跟踪
实验 4 [bx] 和 loop 的使用
实验 5 编写、调试具有多个段的程序
实验 6 实践课程中的程序
实验 7 寻址方式在结构化数据访问中的应用
实验 8 分析一个奇怪的程序
实验 9 根据材料编程
实验 10 编写子程序
课程设计 1
实验 11 编写子程序
实验 12 编写 0 号中断的处理程序
实验 13 编写、应用中断例程
实验 14 访问 CMOS RAM
实验 15 安装新的 int9 中断例程
实验 16 编写包含多个功能子程序的中断例程
实验 17 编写包含多个功能子程序的中断例程
课程设计 2