汇编语言第十五章外中断小白笔记-创新互联

15.1 接口芯片和端口

pc 系统的接口卡和主板上,装有各种接口芯片。这些外设接口芯片内部有若干寄存器,cpu将这些寄存器当作端口来访问。

我们提供的服务有:成都网站设计、网站制作、外贸营销网站建设、微信公众号开发、网站优化、网站认证、呼图壁ssl等。为1000+企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的呼图壁网站制作公司

cpu通过端口和外部设备进行联系。

15.2 外中断信息

来自外部的中断信息

外部中断原有两类:

第一类:可屏蔽中断源

cpu是否响应中断要看标志寄存器。if=1的话,执行完当前指令后去响应中断。if=0的话,不响应中断。

内中断的过程:

(1)取中断类型码n

(2)标志寄存器入栈,if=0,tf=0

(3)cs、ip入栈

(4)(ip)=(n*4),(cs)=(n*4+2)

if=0就是为了屏蔽其他的可屏蔽中断

指令:

sti   ;if=1
cli   ;if=0
第二类:不可屏蔽中断

cpu必须响应。

8086cpu不可屏蔽终端类型码固定为2,所以屏蔽过程中不需要取中断类型码。

过程:

(1)标志寄存器入栈,if=0,tf=0

(2)cs ip入栈

(3)(ip)=(8),(cs)=(0ah)

15.3pc键盘的处理过程

    • 键盘输入

键盘中每个按键相当于一个开关,键盘中有一个芯片对键盘上的每一个键的开关状态进行扫描。

按下一个键时,开关接通,芯片会产生一个扫描码,扫描码说明了按下的键在键盘上的位置。扫描码被送入主板上的相关接口芯片的寄存器中,该寄存器的端口地址为60h

松开按下的键时,也会产生一个扫描码,扫描码说明了松开的键在键盘上的位置,松开按键时产生的扫描码也会被送入60h端口中。

一般按下键盘时的扫描码被叫做通码,松开时的扫描码叫做断码。扫描码长度为一个字节,通码第7位为0,断码第七位为1

就是:

断码=通码+80h
    • 引发9号中断

键盘的输入到达60h端口时,相关的芯片就会向cpu发出中断类型码为9的可屏蔽中断信息。

cpu检测到该中断信息后,如果if=1,则响应中断,引发中断过程,转去执行int9中断例程

    • 执行int9中断例程

(BIOS)系统板的ROM(只读内存)中放有一套程序,称为BIOS(基本输出输入系统)

BIOS提供了int9 的中断例程,用来进行键盘的读取和输出。

:(1)读出60h端口中的扫描码

(2)如果是字符键的扫描码,将该扫描码和它所对应的字符码(ascll)送入内存(一个字节加一个字节=一个字),=中的BIOS键盘缓冲区,如果是控制键的扫描码,则将其转化成状态字节(用二进制记录控制键和切换键状态字节)写入内存中储存状态字节的单元(内存单元)。

(3)对键盘系统进行相关的控制,比如像向芯片发出应答信息

BIOS键盘换缓冲区是系统启动后,BIOS用于存放int9 中断例程所接受的键盘输入的内存区。该内存区可以存储15个键盘输入(15个字型数据),因为int9 中断例程除了接收扫描码外还要产生扫描码对应的字符码,所以在BIOS键盘缓冲区中,一个键盘输入用一个字单元存放,高位存放扫描码,低位存放字符码(ascll)。

assume cs:code,ds:data,ss:stack
data segment
         db 128 dup(0)
data ends

stack segment stack
          db 128 dup(0)
stack ends




code segment

    start:             mov  ax,stack
                       mov  ss,ax
                       mov  sp,128
                        call init_reg
                       call show_keywordstatus



                       mov  ax,4C00h
                       int  21h

    ;===============================
    init_reg:          mov  bx,0B800h

                       mov  es,bx
                       mov  bx,40h
                       mov  ds,bx

                       ret
    ;====================================
    show_status:       push cx
                       push dx
                       push ds
                       push es
                       push si
                       push di

    
    
                       mov  cx,8
     
    showstatus:        mov  dx,0


                       shl  al,1
                       adc  dx,30h
                       mov  es:[di],dl
                       add  di,2
                       loop showstatus
                        

                       pop  di
                       pop  si
                       pop  es
                       pop  ds
                       pop  dx
                       pop  cx

                       ret

    ;===========================
    show_keywordstatus:

                       mov  si,17h
    testA:             
                       mov  di,160*10+40*2
                       mov  al,ds:[si]
                      
                       call show_status

                       jmp  testA
                       ret


code ends

end start
15.4 编写int9中断例程

键盘的输入处理过程:

  1. 键盘产生扫描码

  1. 扫描码送入60h端口

  1. 引发9号中断

  1. cpu执行int9中断例程处理键盘输入

编程:在屏幕中依次显示'a'~'z' esc后改变颜色。

由于cpu执行速度太快,所以要在每一次输入后都进行好多次循环来延迟时间。

assume cs:code
stack segment
          db 128 dup (0)
stack ends



code segment
    start:mov  ax,stack
          mov  ss,ax
          mov  sp,128
    
          mov  ax,0b800h
          mov  es,ax
          mov  ah,'a'
    s:    mov  es:[160*12+40*2],ah


          call delay

          inc  ah
          cmp  ah,'z'
          jna  s
          mov  ax,4c00h
          int  21h



    delay:push ax
          push dx
          mov  dx,10h
          mov  ax,0

    s1:   sub  ax,1
          sbb  dx,0
          cmp  ax,0
          jne  s1
          cmp  dx,0
          jne  s1
          pop  dx
          pop  ax
          
          
          ret





code ends

    end start

改变颜色

那个咱就是说代码一定不要放到vscode的安装目录中

assume cs:code
stack segment
              db 128 dup (0)
stack ends

data segment
             dw 0,0
data ends



code segment
        start:  mov   ax,stack
                mov   ss,ax
                mov   sp,128
    
                mov   ax,data
                mov   ds,ax

                mov   ax,0
                mov   es,ax

                push  es:[9*4]
                pop   ds:[0]
                push  es:[9*4+2]
                pop   ds:[2]                               ;将原来的int9中断例程,的入口保存在ds:0、ds:2中
                cli
                mov   word ptr es:[9*4],offset int9
                mov   es:[9*4+2],cs                        ;在中断向量表中设置新的int9 中断例程的入口地址
                sti





                mov   ax,0b800h
                mov   es,ax
                mov   ah,'a'
        s:      mov   es:[160*12+40*2],ah


                call  delay

                inc   ah
                cmp   ah,'z'
                jna   s

                mov   ax,0
                mov   es,ax

                push  ds:[0]
                pop   es:[9*4]
                push  ds:[2]
                pop   es:[9*4+2]                           ;将中断向量表中int9中断例程的入口恢复为原来的地址





                mov   ax,4c00h
                int   21h



        delay:  push  ax
                push  dx
                mov   dx,10h
                mov   ax,0

        s1:     sub   ax,1
                sbb   dx,0
                cmp   ax,0
                jne   s1
                cmp   dx,0
                jne   s1
                pop   dx
                pop   ax
          
          
                ret


        ;======================================
        int9:   push  ax
                push  bx

                push  es

                in    al,60h                               ;从端口60h读取键盘的输入数据

        ;原来的int调用是(取中断码类型)->(标志寄存器入栈)->(if=0,tf=0)->(cs、ip入栈)->(ip=n*4,cs=n*4+2)
        ;我们将地址放到ds中,所以第一步可省,那么就剩(标志寄存器入栈)->(if=0,tf=0)->(cs、ip入栈)->(ip=n*4,cs=n*4+2)
        ;(cs、ip入栈)->(ip=n*4,cs=n*4+2)==call dword ptr ds:[0]
        ;那么就剩(标志寄存器入栈)->(if=0,tf=0)->call dword ptr ds:[0]三步
        ;
        ;






                pushf                                      ;标志寄存器入栈
        ;   pushf
        ;   pop   bx
        ;   and   bh,11111100b    ;标志寄存器if=tf=0
        ;   push  bx
        ;   popf
                call  dword ptr ds:[0]                     ;模拟int指令,调用原来的int9中断例程

                cmp   al,1
                jne   int9ret

                mov   ax,0b800h
                mov   es,ax
                inc   byte ptr es:[160*12+40*2+1]          ;属性值加1改变颜色


        int9ret:pop   es
                pop   bx
                pop   ax
                iret


code ends

    end start
15.5安装新的int9中断例程序

按下F1后屏幕颜色改变

大概思路就是先将自己写好的int9机器码复制粘贴到0:204

需要先将老int9的csip存到0:200

然后改变中断信息表int9为新的int9的csip

新的int9中会使用call调用老的int9

然后进行判断如果是某个键就进行啥啥

其实就是在原来的int9前边加了一点东西

assume cs:code

stack segment stack
          db 128 dup(0)
stack ends




code segment

    start:  mov   ax,stack
            mov   ss,ax
            mov   sp,128


            push  cs
            pop   ds

            mov   ax,0
            mov   es,ax


            mov   si,offset int9
            mov   di,204h
            mov   cx,offset int9end-offset int9
            cld

            rep   movsb

            push  es:[9*4]
            pop   es:[200h]
            push  es:[9*4+2]
            pop   es:[202h]

            cli
            mov   word ptr es:[9*4],204h
            mov   word ptr es:[9*4+2],0
            sti
          



            mov   ax,4C00h
            int   21h

    int9:   push  ax
            push  bx
            push  cx

            push  es
            in    al,60h

            pushf
            call  dword ptr cs:[200h]

            cmp   al,3bh
            jne   int9ret

            mov   ax,0b800h
            mov   es,ax
            mov   bx,1
            mov   cx,2000
    s:      inc   byte ptr es:[bx]

            add   bx,2
            loop  s


    int9ret:pop   es
            pop   cx
            pop   bx
            pop   ax
            iret
    int9end:nop



code ends

end start

实验15 安装新的int9中断例程

按下“A”后除非不松开,只要松开就出现满屏的"A"

直接根据前边那个改的

先将老int9挪到一边,在新得int9中用call调用老int9

新的int9可以在调用之后加一些功能

assume cs:code

stack segment stack
          db 128 dup(0)
stack ends

code segment

    start:  mov   ax,stack
            mov   ss,ax
            mov   sp,128


            push  cs
            pop   ds

            mov   ax,0
            mov   es,ax


            mov   si,offset int9
            mov   di,204h
            mov   cx,offset int9end-offset int9
            cld

            rep   movsb

            push  es:[9*4]
            pop   es:[200h]
            push  es:[9*4+2]
            pop   es:[202h]

            cli
            mov   word ptr es:[9*4],204h
            mov   word ptr es:[9*4+2],0
            sti
          



            mov   ax,4C00h
            int   21h

    int9:   push  ax
            push  bx
            push  cx

            push  es
            in    al,60h

            pushf
            call  dword ptr cs:[200h]

            cmp   al,1eh+80h
            jne   int9ret

            mov   ax,0b800h
            mov   es,ax
            mov   bx,0
            mov   cx,2000
    s:      mov  byte ptr es:[bx],'A'

            add   bx,2
            loop  s


    int9ret:pop   es
            pop   cx
            pop   bx
            pop   ax
            iret
    int9end:nop



code ends

end start

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧

网站名称:汇编语言第十五章外中断小白笔记-创新互联
浏览地址:https://www.cdcxhl.com/article30/didspo.html

成都网站建设公司_创新互联,为您提供用户体验定制网站网页设计公司品牌网站建设企业建站品牌网站制作

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

小程序开发