《汇编语言》第十三章 int指令

本文详细介绍了汇编语言中的int指令,包括其格式、执行流程及应用。通过int指令,程序员可以主动触发中断,执行特定功能,如在DOS和BIOS中调用中断例程。此外,还讲解了编写中断服务程序的过程,涉及中断向量表的设置和iret指令的使用。最后,讨论了BIOS和DOS提供的中断例程及其安装过程,以及如何利用这些中断例程进行屏幕输出等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第13章 int 指令

中断信息可以来自CPU的内部和外部,当CPU的内部有需要处理的事情发生的时候,将产生马上需要处理的中断信息,引发中断过程。

这一章,我们要讲解另一种重要的内中断,由int指令引发的中断

13.1 int指令

int指令的格式为int n 指令,相当于引发一个n号中断的中断过程,执行情况如下:

  1. 取中断类型码n;
  2. 标志寄存器入栈,IF=0,TF=0;
  3. CS,IP入栈;
  4. 修改IP,CS,跳转到中断程序处理入口。

注意,我们前面所说的中断都是被动触发的,当满足某种错误的条件,就会触发相关错误指令,而int指令是主动触发的,这种区别一定要清楚。

int 指令在程序中的任何地方都可以被加载触发。

13.2 编写供应用程序调用的中断历程。

编程
要求:求一word型数据的平方
参数:(ax)=要计算的数据。
返回值:dx,ax中存放结果的高16位和低16位。
举例应用: 2*3456^2

assmue cs:code

code segment
    start:  mov ax,3456
            add ax,ax
            adc dx,dx
            mov ax,4cooh
            int 21
code ends
end start

分析一下,我们要做以下3部分工作。

  1. 编写实现求平方功能的程序。
  2. 安装程序,将其安装在0号内存出
  3. 设置中断向量表,将程序的入口地址保存在7ch表向中,使其成为入口。
assume cs:code

code segment
start:  mov ax,cs
        mov ds,ax
        mov si,offset sqr
        mov ax,0
        mov es,ax
        mov di,200g
        mov cx,offset sqrend-offset sqr
        cld
        rep movsb

        mov ax,0
        mov es,0
        mov word ptr es:[7ch*4],200h
        mov word ptr es:[7ch*4+2],0

        mov ax,4c00h
        mov int 21h

sqr:    mul ax
        iret
sqrend: nop

code ends
end start     

注意,在执行程序结束后,应该调用iret:
pop IP
pop CS
pop f

功能是调出地址和标志寄存器的值。

程序2

功能:将一个全是字母,以0结尾的字符串,转换为大写。
参数:ds:si指向字符串的首地址。
应用举例:将data段中的字符串转换为大写。

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,4cooh
        int 21h
code ends
end start

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
captialend: nop

code ends
end start

注意:不能向段寄存器中加入单纯的数据,必须要使用相关寄存器。

mov ax,cs
mov ds,ax

可以直接向偏移地址中加入offset的相关信息。

设置ds:si指向源地址
设置es:di指向目的地址

s结尾段地址,i结尾偏移地址

代码段寄存器 DS(Data Segment):
堆栈段寄存器 ES(Extra Segment);

SI(Source Index):源变址寄存器
DI(Destination Index):目的变址寄存器

这个对偏移地址有效,这种操作是你需要明确的。

13.3 对int,iret和栈的深入理解

通过使用int程序,可以停止当前,然后运行相关程序来修改原来的命令。

我们调用中断程序中,我们的CS:IP放入栈,而之后用iret来将取出栈中。

我们知道CS:IP来栈中的相对位置。

我们可以在中断程序中来修改栈中的CS:IP地址,之后当执行iret程序时,我们并不会回到原来的地址,而是回到我们修改过的地址。

这节就是讲了这点内容,然后就是一些相关例子代码,看明白即可。

编程 在屏幕中间显示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

可以看出,这里关于 7ch 的中断程序类似loop s指令。

下面就是关于7ch的中断程序:

    lp: push bp
        mov dp,sp
        dec cx
        jcxz lpret
        add [bp+2],bx
lpret:  pop bp
        iret

这里的dp寄存器是一个浮动的栈游标,空,bp,ip,cs,而[bp+2],这个明显指向IP地址。
而bx在进入该程序前是se到s的相对地址,负数,然后加上就能往前移动。
如果cx==0,那么直接跳到退出的环节,而不是来修改栈中的IP地址,这样,程序就能很自然的进行下面的语句了。

13.4 BIOS和DOS所提供的中断例程

在系统版的ROM中存放着一套程序,被称为BIOS(基本输入输出系统),BIOS中主要包含以下几部分内容。

  1. 硬件系统的检测和初始化程序。
  2. 外部中断和内部中断历程。
  3. 用于对外部硬件设备进行I/O操作的中断历程。
  4. 其他和硬件相关的中断历程。

操作系统DOS也提供了中断历程,从操作系统的角度来看,DOS的中断历程就是操作性向程序猿提供的编程资源,可以供程序猿自由的发挥。

BIOS和DOS所提供的中断历程中包含了许多子程序,这些子程序实现了程序猿在编程的时候经常需要用到的工程。可以用int指令直接调用BIOS和DOS提供的中断历程,来完成某些工作。

13.5 BIOS和DOS中断例程的安装过程

前面我们编写的安装程序,我们可以放在内存中,别的程序在运行时都可以调用。

而BIOS和DOS提供的中断例程是如何安装到内存中的呢?
1. 开机后,CPU一加点,初始化(CS)=0FFFFH,(IP)=0,自动从0FFFFH:0单元开始执行程序。
0FFFF:0处有一条跳转指令,CPU执行该指令后,转去执行BIOS中的硬件系统检测和初始化程序。
2. 初始化程序将建立BIOS所支持的中断向量,即将BIOS提供的中断例程的入口地址登记在中断向量表中。注意,对于BIOS所提供的中断例程,只需要将入口登记在中断向量表中即可,因为它们是固化到ROM中的程序,一直在内存中存在,所以,不用我们自己编写和安装,这个道理要明确的。
3. 操作系统检测和初始化完成后,调用int 19h进行操作系统的引导。从此将计算机交由操作系统控制。
4. DOS启动后,除完成其他工作外,还要将所提供的中断例程装入内存,并建立相应的中断向量,这些是操作系统的,软件层间而非固化在ROM的硬件层面上。

13.6 BIOS中断例程应用

int 10h 中断程序是BIOS提供的中断历程,其中包含了多个和屏幕输出相关的子程序。

一般来说,一个供程序猿调用的中断例程中往往包含多个子程序,中断例程内部用传递进来的参数来决定执行哪一个程序。BIOS和DOS提供的中断例程,都用ah来传递内部子程序的变化

下面看一下int 10h中断历程的设置光标位置功能。

mov ah,2    ;置光标
mov bh,0    ;第0页
mov dh,5    ;dh中放行号
mov dl,12   ;dl中放列号
int 10h

ah=2,表示调用10h中的2号子程序,功能为重制光标的位置。

bh中页号的含义:内存地址空间中,B800H~BFFFH共32kb的空间,为80*25彩色字符模式的显示缓冲区。一屏的内容在显示缓冲区中共占4000个字节。

显示缓冲区分8页,每页4KB,显示器可以显示任意一页的内容。一般情况下,显示第0页的内容。

在看看int 10h中段例程的在光标位置显示字符的功能

mov ah,9    ;在光标处显示字符
mov al,'a'  ;字符
mov bl,7    ;颜色属性
mov bh,0    ;第0页  
mov cx,3    ;字符重复个数
int 10h

两个程序结合可以在屏幕中间显示字符,先把光标放到中间,之后显示字符,就是这样,很简单。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值