汇编学习记录13 INT指令

1.INT指令

  • int指令格式为:int n,n为中断码的类型,功能是引发对应中断码的中断
  • int指令执行的时候分为四步:
    (1)从中断向量表中取得n号中断所对应的程序入口地址
    (2)将标志寄存器入栈,然后设置TF和IF位的值为0
    (3)CS和IP依次序入栈
    (4)跳转到程序入口地址(将IP设置为n* 4,将CS设置为n *4+2)
  • 所以int指令其实从效果上来看,跟call指令有些相似,都是保存现场,调用一段程序

2.编写供应用程序调用的中断程序的方法

(1)实现中断程序功能
(2)将中断程序安装在0000:0200处(上一讲说过中断向量表的0000:0200~0000:02FF位置一般是空白的)
(3)设置中断向量表,使发生对应中断的中断号对应到编写出来的中断程序(一个表项两个字)

注意:
(1)如果想要在中断程序执行完毕以后返回到原来程序执行的位置,可以调用iret指令返回。(iret指令表示将IP,CS和标志寄存器依次出栈后跳转)int指令和iret指令的配套使用同,call指令和ret指令配套使用有相似之处.
(2)一般在编写中断例程和子程序的时候,我们都会将程序要用到寄存器先push到栈中保存起来,以免影响主程序的功能

3.用中断例程完成loop指令的功能(int,iret指令对应栈机制的深入理解)

示例代码:

;数据传送示例代码,调用中断7cH

assume cs:code
code segment
start:
  mov ax,0b800H
  mov es,ax
  mov di,160*12 ; 设置显存位置

  mov bx,offset s-offset se ; BX寄存器向子程序中传递se到s的偏移值
  mov cx,80 ;循环打印80个‘!’
S:
  mov byte ptr es:[di],'!'
  add di,2
  int 7cH ; 跳转到中断号为7c的中断处理程序中去,实现循环到S
se: nop

  mov ax,4c00H
  int 21H

code ends
end start

; 7cH中断例程

  push bp ; 此程序将要用到bp,故先保存bp的值
  mov bp,sp
  dec cx ; 实现loop指令的CX减1
  jcxz lpret ; 
  add [bp+2],bx ; 如果不等于0,则返回到开始的地方
lpret:
  pop bp
  iret
 

解释:
(1)在执行中断指令int 7cH时,我们将标志寄存器,CS和IP都压入了栈中,此时栈顶存放的应该是程序正常执行下一条指令的偏移位置
(2)我们在中断例程中用bp记录例程开始时栈顶的位置(其实这个程序可以不用bp,但是例程中是有可能修改sp的值的,为严谨我们还是将bp入栈),bx从外面传递进来了外程序段的偏移值
(3)我们看到中断例程的add那一条指令,其实就是将栈顶的下一个元素(也就是IP的值)加上了外程序段偏移值bx,从而实现了修改IP,实现loop

4.BIOS和DOS提供的中断例程

  • BIOS程序(Basic I/O System)放在计算机系统板的ROM中,主要包括:
    (1)硬件系统检测和初始化程序
    (2)提供外部中断和内部中断例程
    (3)用于对硬件设备进行I/O操作的中断例程
    (4)其他和硬件系统相关的中断例程

  • BIOS和DOS均提供了中断例程,从操作系统角度看,DOS的中断例程就是操作系统提供给程序员的编程资源。在DOS和硬件设备相关的中断例程中,一般都调用了BIOS的中断例程

  • BIOS和DOS提供的中断例程的安装:
    (1)开机的瞬间,CPU一加电,就会初始化CS=FFFFH,IP=0,自动从FFFF:0单元(CPU开机执行指令)开始执行程序,这个位置有一条跳转指令,会跳转到BIOS程序中执行系统检测和初始化指令
    (2)系统检测完毕后,初始化程序将建立BIOS所支持的中断向量表(即将BIOS提供的中断例程登记在中断向量表中)
    (3)硬件检测和初始化完成以后,执行int 19H,进行操作系统的引导。从此计算机交给操作系统(DOS)控制
    (4)DOS启动完成以后,除了完成其他工作,还会将DOS本身提供的中断例程装入内存,并建立相应中断向量。(有的DOS中断例程是调用了BIOS的中断例程)

5.BIOS提供的中断例程应用举例

  • int 10H 中断例程是BIOS提供的中断例程,其中包含了多个和屏幕输出相关的子例程(子例程:一般来说一个可供程序员调用的例程中包含了许多个子程序,称作子例程)。中断例程的内部接受外部传入的参数,来决定执行哪一个子程序。在BIOS和DOS提供的中断例程中,都用ah寄存器来传递内部子程序编号。

代码举例:
以下代码实现把光标设置到第0页,第5行,第12列

mov ah,2 ; 调用2号子程序,设置光标
mov bh,0 ; 在第0页
mov dh,5 ; 行号为5
mov dl,12 ; 列号为12
int 10H

(书中还例举出当ah=9的时候,10号中断可以实现在光标处显示字符的功能,更多的BIOS中断可以参考网上资料)

  • int 21H中断例程是DOS提供的中断例程,其中包含了许多DOS提供给程序员在编程时调用的子程序。如我们经常用到的程序返回功能:
mov ax,4c00H
int 21H

这个语句实际上是:

mov ah,4cH ;调用4c号子程序,功能是程序返回
mov al,0 ; 程序的返回值为0
int 21H

代码举例:
以下代码实现在光标位置显示字符串。(21H中断号的9号子程序,可以实现此功能,它将会输出ds:dx指向的字符串,字符串以‘$’结尾)

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

附:实验说明

要求:编写一个程序分别在屏幕的第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 ; 采用10号中断的2号子程序(将光标设置在指定位置)
    int 10H 

    mov dx,ds:[bx] ; 参数dx传入21号中断的9号子程序(ds:dx指向要显示字符串的位置,以‘$’结尾)
    mov ah,9
    int 21H
    inc si
    add bx,2
    loop ok

    mov ax,4c00H
    int 21H

code ends
end start

实验截图:

汇编学习记录13 INT指令_第1张图片
12345.GIF

你可能感兴趣的:(汇编学习记录13 INT指令)