13.3 对int,iret和栈的深入理解
检测点13.1
(1)这道我认为主要是判断
add [bp+2],bx
这里是修改IP地址,即向前跳转距离,也即bx的范围。bx为十六位寄存器,范围在-32768~32767,即最大转移位移为32768
(2)
测试程序:
assume cs:code data 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 mov bx,offset flag-offset flagend flag: cmp byte ptr ds:[si],0 je ok mov al,ds:[si] mov byte ptr es:[di],al mov byte ptr es:[di+1],2 inc si add di,2 int 7ch flagend:nop ok: mov ax,4c00h int 21h code ends end start
中断例程:
assume cs:code code segment start: ;将程序移入指定空闲区域 mov ax,cs mov ds,ax mov si,offset do7c mov ax,0 mov es,ax mov di,200h mov cx,offset do7cend-offset do7c cld rep movsb ;设置中断向量 mov ax,0 mov es,ax mov word ptr es:[7ch*4+2],0 mov word ptr es:[7ch*4],200h mov ax,4c00h int 21h do7c: ;设置IP位置 push bp mov bp,sp add ss:[bp+2],bx pop bp iret do7cend:nop code ends end start
13.4 BIOS和DOS所提供的中断例程
通常在系统板的ROM中存放着一套程序,称为BIOS(基本输入输出系统),BIOS中主要是包含了以下几部分内容
- 硬件系统的检测和初始化程序
- 外部中断和内部中断的中断例程
- 用于对硬件设备进行I/O操作的中断例程
- 其他和硬件相关的中断例程
13.5 BIOS和DOS中断例程的安装过程
BIOS和DOS中断例程的安装过程
- 开机后,CPU一加电,初始化(CS)=0FFFFH,(IP)=0,自动的会从FFFF:0的单元开始执行程序,需要注意的是FFFF:0这个地址是在BIOS的系统范围当中的,所以我们不能去更改。在FFFF:0处有一条跳转的指令,CPU在执行这条指令之后,会转去执行BIOS中的硬件系统检测和初始化程序
- 初始化程序会去建立BIOS所支持的中断向量,然后会将BIOS提供的中断例程的入口地址登记在中断向量表当中
- 硬件系统检测和初始化完成之后,会去调用int 19h进行操作系统的引导,之后计算机就会交由操作系统来控制,这里需要去注意的是,是先去调用int 19h引导操作系统启动的,所以int 19h的中断例程不能由DOS来提供
- DOS启动之后,除了完成其他工作之外,还会将它所提供的中断例程装入内存,并且去建立相应的中断向量
检测点 13.2
(1)错误,无法改变。
(2)错误,硬件应该是BIOS的中断例程
13.6 BIOS中断例程应用
在显示缓冲区B8000H~B8FFFFH共32KB空间,为80*25彩色字符模式的显示缓冲区。一屏内容占4000字节。显示缓冲区共8页,每4KB一页。
assume cs:code code segment ;设置光标位置 mov ah,2;置光标 mov bh,0;第0页 mov dh,5;dh放行号 mov dl,12;列号 int 10h ;将字符显示到光标位置 mov ah,9;在光标位置显示字符 mov al,'b';字符 mov bl,11001010b;颜色属性 mov bh,0;第0页 mov cx,3;字符重复个数 int 10h mov ax,4c00h int 21h code ends end
13.7 DOS中断例程应用
mov ah,4ch;程序返回(表示调用第21h号中断例程的4ch号子程序) mov al,0;返回值 int 21h
int 21h中断例程在光标处显示字符串功能
ds:dx指向字符串 ;要显示的字符串需用“$”作为结束符 mov ah,9 ;功能号9,表示在光标处显示字符串 int 21h
编程在5行12列显示‘Welcome to masm!’
assume cs:code data 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
实验13 编写,应用中断例程
(1)编写并安装int 7ch中断例程,功能为显示一个用0结束的字符串,中断例程安装在0:200处
参数:(dh)=行号,(dl)=列号,(cl)=颜色,ds:si指向字符串首地址
测试程序
assume cs:code data segment db 'Welcome to masm!BIU',0 data ends code segment start: mov dh,12 mov dl,30 mov cl,2 mov ax,data mov ds,ax mov si,0 int 7ch mov ax,4c00h int 21h code ends end start
中断例程
assume cs:code code segment start: ;将程序写入0:200h mov ax,cs mov ds,ax mov si,offset func mov ax,0 mov es,ax mov di,200h mov cx,offset funcend-offset func;程序长度 cld rep movsb ;程序入口写入中断向量表中 mov ax,0 mov es,ax mov word ptr es:[7ch*4+2],0 mov word ptr es:[7ch*4],200h mov ax,4c00h int 21h func: push ax push di push es ;显示缓冲区地址 mov ax,0b800h mov es,ax ;将已知条件转换为正确的显存地址 mov al,160 mul dh mov di,ax dec dl mov dh,0 add dx,dx add di,dx show: ;判断是否遇到末尾的0 cmp byte ptr ds:[si],0 je ok ;将显示信息写入显示缓冲区 mov al,ds:[si] mov byte ptr es:[di],al mov es:[di+1],cl inc si add di,2 jmp show ok: ;结束 pop es pop di pop ax iret funcend:nop code ends end start
CS:IP和SS:SP在int和iret前后变化
入栈标志寄存器,CS,IP。SP=FFFAH
SS为当前段地址,CS:IP为空闲区域地址
(2)在屏幕中间显示80个'!'
测试程序
assume cs:code code 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
中断程序
assume cs:code code segment start: ;将程序写入0:200h mov ax,cs mov ds,ax mov si,offset func mov ax,0 mov es,ax mov di,200h mov cx,offset funcend-offset func;程序长度 cld rep movsb ;程序入口写入中断向量表中 mov ax,0 mov es,ax mov word ptr es:[7ch*4+2],0 mov word ptr es:[7ch*4],200h mov ax,4c00h int 21h func: push bp mov bp,sp dec cx jcxz ok add ss:[bp+2],bx ok: pop bp iret funcend:nop code ends end start
(3)下面的程序,分别在屏幕的第2,4,6,8行显示4句英文诗
assume cs:code code 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