中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS开发编程 & 发展交流 (开发室) » 关于汇编改写中断入口地址 的问题。
« [1] [2] »
作者:
标题: 关于汇编改写中断入口地址 的问题。 上一主题 | 下一主题
zhushouqqq
初级用户





积分 32
发帖 13
注册 2008-12-2
状态 离线
『楼 主』:  关于汇编改写中断入口地址 的问题。

在程序运行期间 修改了int9的入口地址 程序结束 恢复int9的入口地址
程序的执行从结果上看是正常的 结束后,键盘就锁住了。
以下是代码。

assume cs:codesg,ds:datasg,ss:stacksg
stacksg segment
  db 128 dup(0)
stacksg ends
datasg segment
  int9ip dw 0
  int9cs dw 0

datasg ends
codesg  segment
    start:

    mov     ax,datasg
    mov      ds,ax
    mov     ax,0
    mov     es,ax
    mov     si,0
    mov      dx,es:[9*4]
    mov  word ptr  int9ip,dx
    mov      dx,es:[9*4+2]
    mov word ptr  int9cs,dx        ;保存当前的int 9的中断向量
    ;
    mov  word ptr es:[9*4],offset int99
    mov  word ptr es:[9*4+2],cs ;设置int 9中断向量

    mov     ax,0b800h
    mov     es,ax
    mov     di,160*12+2*40          ;第13行中间开始
    mov     cx,10
    ;
    mov     al,'a'
    mov     ah,7ch                  ;颜色
    mov     es:[di+1],ah
    ;
    s:
    mov     es:[di],al
    call    time
    inc     al
    loop    s                       ;循环显示

    mov      dx,int9ip
    mov  word ptr es:[9*4],dx
    mov      dx,int9cs
    mov word ptr es:[9*4+2],dx      ;恢复int 9中断向量

    mov     ax,4c00h
    int     21h


;----------------------------------
    int99:                           ;到这里 CS IP 标志寄存器 已经由硬件完成入栈
    mov ah,0fch
    mov byte ptr es:[di+1],ah        ;恢复向量表
    iret
;----------------------------------

    ;用于延时
    time proc
         push   ax
         push   bx
         mov    bx,1000h
         mov    ax,0
         s1:
         sub    ax,1
         sbb    bx,0
         cmp    ax,0
         jne    s1
         cmp    bx,0
         jne    s1
         pop    bx
         pop    ax
         ret
    time endp
codesg  ends
end start

继续研究。。。

2008-12-3 18:26
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
本是
银牌会员





积分 2201
发帖 789
注册 2005-1-27
状态 离线
『第 2 楼』:  

你的问题出在这段程序上,你的ES被替换后未做现场保护,只要在前面加PUSH ES,在后面加POP ES就可以了。我在编VtMagiC.com时也有过如此疏漏导致的调试多次失败。汇编就是这样的!所以人家要用VB、VC啦!

    mov     ax,0b800h
    mov     es,ax
    mov     di,160*12+2*40          ;第13行中间开始
    mov     cx,10
    ;
    mov     al,'a'
    mov     ah,7ch                  ;颜色
    mov     es:[di+1],ah
    ;
    s:
    mov     es:[di],al
    call    time
    inc     al
    loop    s                       ;循环显示



my major is english----my love is dos----my teacher is the buddha----my friends--how about U
2008-12-3 21:16
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
zhushouqqq
初级用户





积分 32
发帖 13
注册 2008-12-2
状态 离线
『第 3 楼』:  

恩  ES确实没有保护好
以下是改后的代码 我全贴出来吧, 复制过去,编译下就能运行
我想实现的功能是这样的, 在逐个显示字符期间, 如果有键盘按键。就改变原来的字符颜色。 并用改写int 9 中断的方式去实现。
assume cs:codesg,ds:datasg,ss:stacksg
stacksg segment
  db 128 dup(0)
stacksg ends
datasg segment
  int9ip dw 0
        int9cs dw 0
datasg ends
codesg        segment
    start:

    mov     ax,datasg
                mov                        ds,ax
    mov     ax,0
    mov     es,ax
                mov     si,0
                mov                        dx,es:[9*4]
    mov        word ptr  int9ip,dx
                mov                        dx,es:[9*4+2]
    mov word ptr        int9cs,dx        ;保存当前的int 9的中断向量
                ;
    mov  word ptr es:[9*4],offset int9
    mov  word ptr es:[9*4+2],cs ;设置int 9中断向量
    push                es
    mov     ax,0b800h
    mov     es,ax
    mov     di,160*12+2*40          ;第13行中间开始
    mov     cx,10
                ;
    mov     al,'a'
    mov     ah,7ch                  ;颜色
    mov     es:[di+1],ah
                ;
    s:
    mov     es:[di],al
    call    time
    inc     al
    loop    s                       ;循环显示

    pop                        es
    mov                        dx,int9ip
                mov        word ptr es:[9*4],dx
                mov                        dx,int9cs
    mov word ptr es:[9*4+2],dx      ;恢复int 9中断向量

    mov     ax,4c00h
    int     21h


;----------------------------------
    int9:                           ;到这里 CS IP 标志寄存器 已经由硬件完成入栈
    mov ah,0fch
    mov byte ptr es:[di+1],ah        ;恢复向量表
    iret
;----------------------------------

    ;用于延时
    time proc

         push   ax
         push   bx
         mov    bx,1000h
         mov    ax,0

         s1:
         sub    ax,1
         sbb    bx,0
         cmp    ax,0
         jne    s1
         cmp    bx,0
         jne    s1
         pop    bx
         pop    ax
         ret
    time endp
codesg        ends
end start

程序运行 和第一次的结果一样, 在显示字符期间按键盘,字符颜色就改变。 但是,程序运行结束   键盘就不能用了,输入不了字符了。
另外,我在time子程序里 S标号的上一句加了 int 9让程序自身产生中断。 运行结果是,字符的颜色改变,键盘能用。 这就奇怪了直接在程序里写int 9和按键触发的int 9应该一样呀 都是是cs ip 寄存器 入栈。iret 恢复。

2008-12-4 09:58
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
本是
银牌会员





积分 2201
发帖 789
注册 2005-1-27
状态 离线
『第 4 楼』:  

DOS中断最要注意重入问题,要调用原中断例程,要在int99(新中断例程)中加入pushf和call dword ptr ds:int9ip链接原中断,才能继续键盘操作。

另外,你的新例程中,DI值来自何处?而且也没有处理键盘输入的程序行,应该是程序不完整吧!因为贴出来的程序段根本不需要挂在int9上。

[ Last edited by 本是 on 2008-12-4 at 11:43 ]



my major is english----my love is dos----my teacher is the buddha----my friends--how about U
2008-12-4 11:28
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
zhushouqqq
初级用户





积分 32
发帖 13
注册 2008-12-2
状态 离线
『第 5 楼』:  

mov     di,160*12+2*40          ;第13行中间开始
因为这个中断例程只是这个程序用 程序执行玩后 就要恢复的 所以这个DI 在在例程中没有重新赋值。
“DOS中断最要注意重入问题,要调用原中断例程,要在int99(新中断例程)中加入pushf和call dword ptr ds:int9ip链接原中断,才能继续键盘操作。”
对这句话不是很理解。
中断产生,也就是我按下键盘 产生的int 9中断。 硬件完成了Cs IP 标志寄存器的入栈, 然后就是调用我的int99 我只要在中断历程中iret一下就可以了。
鄙人不才,还望进一步指点。

2008-12-4 12:11
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
zhushouqqq
初级用户





积分 32
发帖 13
注册 2008-12-2
状态 离线
『第 6 楼』:  

是不是这样,
我在程序中只是执行了 我定义的int 9中断 但是还要必须执行一次系统原来的int 9中断。

2008-12-4 12:44
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
zhushouqqq
初级用户





积分 32
发帖 13
注册 2008-12-2
状态 离线
『第 7 楼』:  

中断例程修改如下:
    int9:                           ;到这里 CS IP 标志寄存器 已经由硬件完成入栈

    mov ah,0fch
    mov byte ptr es:[di+1],ah       ;恢复向量表

    pushf                push ax
                and ah,11111100b
                pop ax

                ;push int9cs
                ;push int9ip
    ;jmp dword ptr int9ip            ;高地址是cs 低地址是IP
                call dword ptr ds:int9ip         ;模仿 调用系统的int 9

    iret

运行正常  看来还要好好的深入研究中断
系统的int 9中断 做了些什么。

2008-12-4 12:59
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
zhushouqqq
初级用户





积分 32
发帖 13
注册 2008-12-2
状态 离线
『第 8 楼』:  

谢谢 本是
这个问题困扰了我三天。

2008-12-4 13:00
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
本是
银牌会员





积分 2201
发帖 789
注册 2005-1-27
状态 离线
『第 9 楼』:  

不用谢!不过,我觉得你需要系统地学习一些系统知识,如《MS-DOS高级开发指南——编程人员必备的高级技术参考书》(希望电脑公司),里面对中断编程讲得很细,当然网上也应该有资料的。



my major is english----my love is dos----my teacher is the buddha----my friends--how about U
2008-12-4 13:45
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
netwinxp
高级用户





积分 741
发帖 366
注册 2007-7-25
状态 离线
『第 10 楼』:  

硬件中断服务程序要注意与硬件的“沟通”,你的INT 9既没有对产生INT 9的原因进行“处理”,也没有回调老的中断服务程序进行默认的“处理”,于是,按一下键,就会一直在产生INT 9。

2008-12-5 11:15
查看资料  发短消息 网志   编辑帖子  回复  引用回复
本是
银牌会员





积分 2201
发帖 789
注册 2005-1-27
状态 离线
『第 11 楼』:  



  Quote:
Originally posted by netwinxp at 2008-12-5 11:15:
硬件中断服务程序要注意与硬件的“沟通”,你的INT 9既没有对产生INT 9的原因进行“处理”,也没有回调老的中断服务程序进行默认的“处理”,于是,按一下键,就会一直在产生INT 9。

真正的硬件高手!一直喜欢看高手回的贴子。



my major is english----my love is dos----my teacher is the buddha----my friends--how about U
2008-12-5 11:22
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
zhushouqqq
初级用户





积分 32
发帖 13
注册 2008-12-2
状态 离线
『第 12 楼』:  



  Quote:
Originally posted by netwinxp at 2008-12-5 11:15:
硬件中断服务程序要注意与硬件的“沟通”,你的INT 9既没有对产生INT 9的原因进行“处理”,也没有回调老的中断服务程序进行默认的“处理”,于是,按一下键,就会一直在产生INT 9。

不是一直产生int 9 而是8259A不让通过 因为在接受一个中断后 8259A的EOI位一直为0,不在接受同级或以下级别的中断(被屏蔽了)。 直到EOI标志位为1。 我想,要在进行一次默认的“处理”,其目的是让EOI置1.代码修改后 测试通过

int9:   
   mov ah,0fch
     mov byte ptr es:[di+1],ah       ;恢复向量表
    mov al,20h
     out 20h,al ;置EOI 为1
    iret

2008-12-12 09:15
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
netwinxp
高级用户





积分 741
发帖 366
注册 2007-7-25
状态 离线
『第 13 楼』:  

其实你的程序根本没必要使用INT 9,除非迫不得已,否则不推荐任意修改硬件中断服务程序。
...
RE:
...
;寄存器入栈
;清理标志寄存器
mov  ax,1100H
int  16H
jnz   EXIT
;寄存器出栈
;用于显示的语句
...
jmp RE
EXIT:;退出处理
...

[ Last edited by netwinxp on 2008-12-12 at 09:31 ]

2008-12-12 09:25
查看资料  发短消息 网志   编辑帖子  回复  引用回复
zhushouqqq
初级用户





积分 32
发帖 13
注册 2008-12-2
状态 离线
『第 14 楼』:  

这个只是书上一个运行不起来的代码。只是为了自己理解。

2008-12-12 09:46
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
sanchuan
初级用户





积分 113
发帖 51
注册 2008-11-16
来自 武汉
状态 离线
『第 15 楼』:  

能够引起探讨的好贴,顶



三川一笑
2008-12-30 17:10
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
« [1] [2] »
请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: