鱼C论坛

 找回密码
 立即注册
查看: 3079|回复: 0

第15章,外中断的疑惑

[复制链接]
发表于 2022-3-28 15:50:24 | 显示全部楼层 |阅读模式
5鱼币
int指令在执行的时候,cpu进行下面的工作():
1.取中断类型码n
2.标志寄存器入栈
3.if=0,tf=0
4.cs,ip入栈
5.(ip)=(n*4),(cs)=(n*4+2)
程序功能:在屏幕中间依次显示“a”~“z”,并可以让人看清。在显示的过程中,按下'Esc'键后,改变显示的颜色。

思考了很久都搞不懂,第十五章,模拟int 9那里的情况,当我按下esc产生外中断,正常情况是上边的1到5步骤.而我们模拟的时候:按下esc,然后cpu检查到端口的扫描码产生外中断9号信息提供申请,cpu检测到中断信息9就开始把标志寄存器入栈,if,tf设置为0,我只是改变了中断向量表的指向的中断例程,第4,5步是在call之后进行的我知道,第1步也是事先知道了.
那么我的问题来了,那么第2,第3步,假如是已经int之后就达到目的了(没有调用中断例程之前),也就是完成了第2,第3步,为什么在模拟的中断例程中需要再来一遍第2,第3步
假如是在根据中断向量表指向的cs,ip跳转后才实现的第2,第3步,那么在新写的int 9里边包含了指向原来的中断例程,也就是下边源码的call dword ptr ds:[0],那不就等于执行了两次重复的动作,模拟第2第3步就显得多余了
因为代码只是改动了中断向量表指向的中断例程,我的理解就是它属于例程后的例程(属于例程的补充),所以我就被它的模拟搞糊涂了,希望大佬讲解,以下为源码:


分割线---------------------------------------------------------------------------------------------------------------------------------------------------
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]        ;将原来的int 9中断例程的入口地址保存在ds:0、ds:2单元中

    mov word ptr es:[9*4],offset int9
    mov es:[9*4+2],cs    ;在中断向量表中设置新的int 9中断例程的入口地址,使得中断的时候执行新的int 9

    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]       ;将中断向量表中int 9中断例程的入口恢复为原来的地址

    mov ax,4c00h
    int 21h

delay:   
    push ax
    push dx
    mov dx,2000h
    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

;------以下为新的int 9中断例程--------------------

int9:   
    push ax
    push bx
    push es

    in al,60h;取60h端口中的扫描码

    pushf
    pushf;一次模拟的,一次还原真实的9号中断寄存器
    pop bx
    and bh,11111100b
    push bx
    popf;if和cf都设置好了,再执行下一步call后,当前cs,ip进栈,还有跳转到对应的cs,ip取执行中断例程
    call dword ptr ds:[0]     ;对int指令进行模拟,调用原来的int 9中断例程/////

    cmp al,1;esc的扫描码为1
    jne int9ret

    mov ax,0b800h
    mov es,ax
    inc byte ptr es:[160*12+40*2+1]  ;如果此时是esc键,属性增加1,改变颜色

int9ret:
    pop es
    pop bx
    pop ax
    iret

code ends

end start





想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-23 00:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表