zoukankan      html  css  js  c++  java
  • 汇编语言-13int指令

    int指令

    int 指令的格式为: int n;n 为中断类型码,它的功能是引发中断过程。

    CPU执行int n指令,相当于引发一个n 号中断的中断过程,过程如下:

    (1) 取中断类型码n;
    (2) 标志寄存器入栈,IF=0, TF=0;
    (3) CS、IP入栈;
    (4) (IP)=(n*4),(CS)=(n*4+2)。

    从此处转去执行n号中断的中断处理程序。

    可以在程序中使用int指令调用任何一个中断的中断处理程序。

    assume cs:code
    code segment
        start:mov ax,0b800h
            mov es,ax
            mov byte ptr es:[12*160+40*2],'!'
            int 0     /*这里调用0号内存中断*/
    code ends
    end start

    程序执行后将在屏幕中间显示一个“ ! ”,然后显示“ Divide overflow" 后返回到系统中。”!”是编程显示的,程序是有做除法,但是在结尾使用了int 0指令。CPU执行int 0指令时,将引发中断过程,执行0号中断处理程序,而系统设置的0号中断处理程序的功能是显示“Divide overflow", 然后返回到系统。

    可见, int指令的最终功能和call指令相似,都是调用一段程序。

    一般情况下,系统将一些具有一定功能的子程序,以中断处理程序的方式提供给应用程序调用。在编程的时候,可以用int 指令调用这些子程序。当然,也可以编写一些中断处理程序供别人使用。

    编写供应用程序调用的中断例程

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

    assume cs:code
    code segment
        start:mov ax,3456    #(ax)=3456
            int 7ch    #调用中断7ch的中断过程,计算ax中的数据的平方,计算结果存在ds(高16位),ax(低16位)中
            add ax,ax    #ds:ax中的值乘以2第一步,低16位相加,如果进位则CF=1
            adc dx,dx    #dx:ax中的值乘以2第二部,高16位相加并加上CF
            mov ax,4c00h
            int 21h
    code ends
    end start

    写中断例程分三步:

    (1) 编写实现求平方功能的程序;
    (2) 安装程序,将其安装在0:200处;
    (3) 设置中断向量表,将程序的入口地址保存在7ch表项中,使其成为中断7ch的中断例程。

    assume cs :code
    code segment
    start:mov ax,cs
        mov ds,ax
        mov si,offset sqr    #设置ds:si指向源地址
        mov ax,0
        mov es,ax
        mov di,200h          #设置es:di指向目的地址
        mov cx,offset sqrend-offset sqr   #设置ex为传输长度
        cld                               #设置传输方向为正
        rep movsb    #从ds:si拷贝到es:di,每拷贝1个字节,cx-1
        
        mov ax,0
        mov es,ax
        mov word ptr es:[7ch*4],200h    #设置7ch中断程序的偏移量
        mov word ptr es:[7ch*4+2],0   #设置7ch中断程序的段地址
        
        mov ax,4c00h
        int 21h
        
    sqr: mul ax
        iret
    sqrend: nop
    
    code ends
    end start

    注意:在中断例程sqr 的最后,要使用iret 指令。用汇编语法描述, iret 指令的功能为:

    pop IP    #偏移地址出栈
    pop CS    #段地址出栈
    popf    #标志寄存器值出栈

    CPU执行int 7ch指令进入中断例程之前,标志寄存器、当前的CS和IP被压入栈中,在执行完中断例程后,应该用iret指令恢复int 7ch执行前的标志寄存器和CS 、IP的值,从而接着执行应用程序。

    int指令和iret 指令的配合使用与call 指令和ret 指令的配合使用具有相似的思路。

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

    assume cs:code
    
    data segment
        db 'conversation',0
    data ends
    
    code segrnent
      start: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
      #把程序放入0:200中
      start:mov ax,cs
            mov ds,ax
            mov si,offset capital
            mov ax,O
            mov es,ax
            mov di,200h
            mov cx,offset capitalend-offset capital
            cld
            rep movsb
            
            #设置7ch中断程序的入口cs:ip
            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]   #把ds:si的值放入cl中
            mov ch,O    #cx高16位重置为零
            jcxz ok    #如果cx为0则跳转,字符串遍历到最后一位是0 (db '',0)
            and byte ptr [si],11011111b    #大写操作
            inc si   
            jmp short change
        ok:pop si
            pop CX
            iret
        capitalend: nop
        
    code ends
    end start

    对int 、iret和栈的深入理解

    编程:用7ch中断例程完成loop指令的功能

    loop s的执行需要两个信息,循环次数和到s的位移,所以,7ch中断例程要完成loop指令的功能,也需要这两个信息作为参数。用cx存放循环次数, 用bx存放位移。

    应用举例: 在屏幕中间显示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

    中断程序

        lp:push bp   #bp入栈保存
            mov bp,sp  #把sp指向的栈顶给bp
            dec cx   #cx-1
            jcxz lpret   #如果cx=0则跳转
            #栈中的情况为:栈顶处是bp原来的数值,下面是se的偏移地址,再下面是s的段地址, 再下面是标志寄存器的值
            add [bp+2],bx    #修改栈中IP指向的位置,bp中为栈顶的偏移地址,所以((ss)*l6+(bp)+2)处为se的偏移地址,将它加上bx中的转移位移就变为s的偏移地址。最后用iret出栈返回,CS:IP即从标号s处开始执行指令。
        lpret:pop bp
            iret

    BIOS和DOS所提供的中断例程

    在系统板的ROM中存放着一套程序,称为BIOS(基本输入输出系统),BIOS中主要包含以下几部分内容。
    (1) 硬件系统的检测和初始化程序;
    (2) 外部中断和内部中断的中断例程;
    (3) 用于对硬件设备进行I/O操作的中断例程;
    (4) 其他和硬件系统相关的中断例程。

    操作系统DOS也提供了中断例程,从操作系统的角度来看,DOS的中断例程就是操作系统向程序员提供的编程资源。

    BIOS和DOS在所提供的中断例程中包含了许多子程序,这些子程序实现了程序员在编程的时候经常需要用到的功能。程序员在编程的时候,可以用int指令直接调用BIOS和DOS提供的中断例程,来完成某些工作。
    和硬件设备相关的DOS中断例程中,一般都调用了BIOS 的中断例程。

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

    (1) 开机后, CPU-加电,初始化(CS)=0FFFFH, (IP)=0, 自动从FFFF:0单元开始执行程序。FFFF:0处有一条转跳指令,CPU执行该指令后,转去执行BIOS中的硬件系统检测和初始化程序。

    (2) 初始化程序将建立BIOS所支持的中断向量,即将BIOS 提供的中断例程的入口地址登记在中断向量表中。注意, 对于BIOS所提供的中断例程,只需将入口地址登记在中断向量表中即可, 因为它们是固化到ROM中的程序, 一直在内存中存在。

    (3) 硬件系统检测和初始化完成后,调用int 19h进行操作系统的引导。从此将计算机交由操作系统控制。

    (4) DOS启动后,除完成其他工作外,还将它所提供的中断例程装入内存,并建立相应的中断向量。

    BIOS中断例程应用

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

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

    (ah)=2 表示调用第10h 号中断例程的2号子程序,功能为设置光标位置,可以提供光标所在的行号(80*25 字符模式下: 0~24) 、列号(80*25 字符模式下: 0~79) ,和页号作为参数。
    (bh)=0, (dh)=5, (dl)= 12, 设置光标到第0 页, 第5 行, 第12 列。

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

    显示缓冲区分为8 页,每页4KB(4000B) ,显示器可以显示任意一页的内容。一般情况下,显示第0页的内容。也就是说,通常情况下, B8000H~B8F9FH中的4000 个字节的内容将出现在显示器上。

    编程:在屏幕的5 行12 列显示3个红底高亮闪烁绿色的'a' 。

    assume cs:code
    code segment
        mov ah,2    #置光标
        mov bh,0    #第0 页
        mov dh,5    #dh中放行号
        mov dl,12    #dl 中放列号
        int 10h
        
        mov ah,9    #在光标位置显示字符
        mov al,'a'   #字符
        mov bl, 11001010b    #颜色属性
        mov bh,0    #第0页
        mov cx,3    #字符重复个数
        int 10h
        
        mov ax,4c00h
        int 21h
    code ends
    end

    DOS中断例程应用

    int 21h 中断例程是DOS 提供的中断例程,其中包含了DOS 提供给程序员在编程时调用的子程序。
    int 21h中断例程的4ch号功能,即程序返回功能,如下:

    mov ah,4ch    #程序返回
    mov al,0    #返回值
    int 21h

    (ah)=4ch表示调用第21h号中断例程的4ch号子程序,功能为程序返回,可以提供返回值作为参数。

    int 21h中断例程在光标位置显示字符串的功能:

    ds:dx指向字符串   #要显示的字符串需用“$“作为结束符
    mov ah,9    #功能号9,表示在光标位置显示字符串
    int 21h

    (ah)=9 表示调用第21h 号中断例程的9 号子程序,功能为在光标位置显示字符串,可以提供要显示字符串的地址作为参数。

    编程:在屏幕的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    #第0 页
        mov dh,5    #dh中放行号
        mov dl,12    #dl 中放列号
        int 10h
        
        mov ax,data
        mov ds,ax
        mov dx,0    #ds:dx指向字符串的首地址data:O
        mov ah,9
        int 21h
        
        mov ax,4c00h
        int 21h
    code ends
    
    end start

    上述程序在屏幕的5行12列显示字符串“Welcome to masm!", 直到遇见“$“(“$“本身并不显示,只起到边界的作用)。

  • 相关阅读:
    SAP CRM销售订单UI上的字段对应的数据库表存储字段:requested start date和end date
    SAP Fiori Elements里Drop down list的实现原理
    使用Fiori Elements创建的SAP UI5应用,如何支持编辑功能
    #开工新姿势#开启一年新征程,云社区叫你来充电啦!
    云小课 | 守护网络安全不是问题,iptables的四表五链为你开启“八卦阵”
    所见即搜,3分钟教你搭建一个服装搜索系统!
    AI辅助宫颈癌筛查技术全球居首,守护者的力量来源是?
    干货分享丨从MPG 线程模型,探讨Go语言的并发程序
    网络知识一箩筐:IP地址划分的那些知识点
    MindSpore:基于本地差分隐私的 Bandit 算法
  • 原文地址:https://www.cnblogs.com/aeolian/p/13187547.html
Copyright © 2011-2022 走看看