(2011.11.04) 汇编_王爽_第13章_学习小结
本章内容:
1. 如何编写供应用程序调用的中断例程
2. 如何使用中断例程实现循环
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
一.BIOS内容补充:
1. BIOS中有许多的中断例程
2. BIOS(基本输入输出系统),主要有以下四方面的内容
01.硬件系统的检测和初始化程序
02.外部中断和内部中断例程
03.用于对硬件设备进行I/O操作的中断例程
04.其他和硬件系统相关的中断例程
二.开机过程中与中断例程相关的
1. 开机 -> CPU通电 -> CS:IP = 0FFFFH:0从CS:IP开始执行
2. -> 建立BIOS支持的中断向量 -> 登记安装入口
3. -> 调用int19进行操作系统引导
4. -> 中断例程装入内存
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
; 程序名称:1302_编写供应用程序调用的中断例程.asm
; 程序功能:将一个全是字母,以零结尾的字符串转化为大写
assume cs:code
data 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
;--------------------------------------------------------------------
; 下面是中断程序 int 7ch的安装程序
assume cs:code
code segment
start:
; ----------------------------------------------------------------------
; 第一步:将程序代码复制到向量表中
mov ax, cs
mov ds, ax
mov si, offset capital
mov ax, 0
mov es, ax
mov di, 200h
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, [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
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
; 程序名称:1303_使用中断例程实现程序的循环.asm
; 程序功能:在屏幕中间显示80个'!'
assume cs:code
code segment
start:
mov ax, 0b800h
mov es, ax
mov di, 160*12
mov bx, offset s - offset se ; 设置从标号se到标号s的转移位置
mov cx, 80
s:
mov byte ptr es:[di], '!'
add di, 2
int 7ch ; 如果(cx)!= 0 ,则转移到标号s处
se:
nop
mov ax, 4c00h
int 21h
code ends
end start
; 7ch的中断例程:
; ------------------------------------------------------------------------------------------------
assume cs:code
code segment
start:
; 第一步:复制代码至中断向量表
; -------------------------------------------------------------------------------------------------
mov ax, cs
mov ds, ax
mov si, offset lp
mov ax, 0
mov es, ax
mov di, 200h
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 ; 先将需要用到的bp放入堆栈中
mov bp, sp ; 将现在的sp移到bp中
dec cx ; cx减1,直到cx为0不再循环
jcxz lpret
add [bp+2], bx ; 将bp+2,因为刚刚程序开始时执行过push操作
; 所以要想获取IP,则需+2,(每push一次,减2)
; 改变原程序中IP的值
; 在程序刚刚进来中断程序前,程序隐含执行了一次
; push popf 之后是 push CS 之后是 push IP 的操作
; 此时IP放在堆栈中的最顶处
lpret:
pop bp
iret ; 程序返回前,从堆栈中获取地址返回
; pop IP -> pop CS -> popf
endlp:
nop
; --------------------------------------------------------------------------------------------------
code ends
end start
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
; 程序名称:实验13_编写中断例程_显示字符串.asm
; 程序要求:编并安装int 7ch中断例程,功能为显示一个用0结束的字符串,中断例程安装在0:200处。
; 程序参数:(dh) = 行号,(dl) = 列号,(cl) = 颜色,ds:si 指向字符串首地址
; 原题目提供的程序:
assume cs:code
data 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
; 开始安装int 7ch
;-------------------------------------------------------------------------------------------
assume cs:code
code segment:
start:
push ds
push bp
push dx
push cx
push si
; 第一步:将代码复制至中断向量表
; -----------------------------------------------------------------------------------------
mov ax, cs
mov ds, ax
mov si, offset showstring
mov ax, 0
mov es, ax
mov di, 200h
mov cx, offset showstringend - offset showstring
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
; 第三步:编写需要执行的中断代码
;---------------------------------------------------------------------------------------------------
showstring:
mul dh, 16 ; 得出行号的地址
add ax, dl ; 得出行列号的地址
mov bx, ax ; 设置bx为显示区的偏移地址
mov ax, ss:[sp] ; 提取原来的数据地址
mov ds, ax
mov ax, 0b800h
mov es, ax ; 设置es的地址为显示缓冲区的段地址
; mov ax, ss:[sp+8] ; 提取需要显示的颜色
mov ax, 0
mov di, ax
showtime:
; 循环准备及判断
mov ch, ds:[di]
mov cl, 0
jcxz showstringend
; 代码执行
mov al, ds:[di]
mov es:[bx], al ; 将字符copy过去
inc bx
mov es:[bx], di ; 将字符属性copy过去
; 循环继续及结束判断
inc bx
inc di
jmp showtime
showstringend:
pop si
pop cx
pop dx
pop bp
pop ds
nop
code ends
end start