如果。。。 发表于 2012-8-18 22:17:23

中断例程的一些小疑问..

首先申明一下,本帖子篇幅有些长,字有些多,废话也有点多。希望好奇的人能耐着性子慢慢看下去,谢谢!看了王爽老师的《汇编语言》和小甲鱼的视频,学习到了实验12实验12的题目是:编写0号中断的处理程序也就是自己编写中断程序,修改系统默认的int 0 的中断例程。要求是在屏幕中间显示“overflow”字符串,为了显眼,我给它加上了绿色。然后,下面是我编的程序,其实也算不上自己编的,差不多就是从书上给copy下来的。但其中的意思我还是理解了。代码如下:

assume cs:code

code segment
start:        mov ax,cs
                mov ds,ax
                mov si,offset do0        ;设置源地址
               
                mov ax,0
                mov es,ax
                mov di,200h                        ;设置目的地址
               
                mov cx,offset do0end - offset do0                ;cx为传输长度
                cld                                 ;正向
                rep movsb
               
                mov ax,0
                mov es,ax
                mov word ptr es:,200h                ;偏移地址
                mov word ptr es:,0                ;段地址
               
                int 0                        ;代码第21行,调用除法溢出中断
                mov ax,4c00h
                int 21h
               
do0:        jmp short do0start
                db 'Overflow!'
do0start:        mov si,offset do0 + 2        ;设置si指向字符串
                       
                        mov ax,0b800h
                        mov es,ax
                        mov di,12*160+36*2                ;设置es:di指向显存空间的中间位置
                       
                        mov cx,9                        ;设置字符串长度cx
           s:        mov al,
                        mov es:,al
                        mov byte ptr es:,2h        ;设置颜色属性
                        inc si
                        add di,2
                        loop s
                       
                        mov ax,4c00h
                        int 21h
       
do0end:                nop

code ends
end start为了验证是否修改了默认的int 0,我在第21行加上了一句 int 0 ,也就是调用了除法溢出中断例程。首先,我在cmd中直接将编译好的1.exe(程序名以1命名的) 运行。结果屏幕一闪而过,我猜想应该是经过了debug窗口后迅速的回到了cmd窗口上,按道理说应该会有我所期待的结果:在屏幕中间输出绿色的“overflow”字符串的,结果cmd窗口还是黑咕隆咚一片,如下图:http://ww3.sinaimg.cn/mw690/92c7cb9bgw1dw16np4si6j.jpg
然后我很是郁闷,因为看小甲鱼演示的时候,屏幕上还出现了令人兴奋的“I Love fishc.com”而我的却漆黑一片。。。。怎能不叫人郁闷的!于是决定我单步调试,找到问题的所在,经过了一番捣鼓,似乎有点进展,我直接用g命令跳转到指令mov ax,4c00hint 21h这个地方,然后屏幕上出现了我期待已久的绿字!如下图:http://ww1.sinaimg.cn/mw690/92c7cb9bgw1dw16ntetfej.jpg不免激动了一把!然后继续往后学习,发现后面调用中断例程的程序都是两个程序,就是说,一个程序负责安装中断例程,另一个则用来调用这个中断例程。然后我有郁闷了,我想,既然分成了两个程序(或文件),先用程序1安装中断例程,然后退出程序1,执行程序2使它触法程序1的中断例程,这样还能得到预期的结果吗?程序2是在程序1关闭以后才调用程序1的,这时候程序1写的那写中断处理代码在内存中不是很容易让别的程序给覆盖或者修改了吗?口说无凭,时间是检验真理的唯一标准嘛。于是我又动手了......然后我写了一个程序2(名字就叫2.exe),2.exe的目的是做出会溢出的除法,这样就可以调用int 0 的除法溢出响应中断了。代码如下:
assume cs:code

code segment
start:        mov ax,1000h
                mov bl,1
                div bl                        ;目的产生除法溢出
               
                mov ax,4c00h
                int 21h
               
code ends
end start为了让1.exe中的除法溢出不影响2.exe,于是我把1.exe中的第21行int 0                        ;代码第21行,调用除法溢出中断给注释了。这样1.exe就是单纯的设置0号中断处理程序,使其在屏幕中间输出字符串。然后按照书上的介绍和小甲鱼的操作,在cmd中先运行1.exe(前提当然是1,2都编译好了)然后在运行2.exe,按照预想的和小甲鱼的实际操作,2.exe运行之后将会在屏幕中间出现绿色的字符串,可奇怪的是我的窗口中依然是黑咕隆咚的,啥也没有。。。。如下图:http://ww4.sinaimg.cn/mw690/92c7cb9bgw1dw16nwfwkij.jpg然后我就纳闷+郁闷啊……怎么回事呢!!诶,还是但步跟踪调试吧,于是我开始debug 2.exe了,幸好2.exe不长,就3句代码。调试如下,结果和我想的差不多:http://ww4.sinaimg.cn/mw690/92c7cb9bgw1dw16o2yv30j.jpg

首先,可以肯定一点,int 0的0号中断的默认处理程序确实被修改了;然后,和我预想的差不多,1.exe中的中断例程的目的是“出现除法溢出后在屏幕中间输出绿色的'overflow'字符串”,可结果却是输出了http://ww1.sinaimg.cn/mw690/92c7cb9bgw1dw16o476d2j.jpg这么一串乱码,我想就是因为1.exe退出后,有些代码数据被其他程序该占用或者改写的原因吧。可是,让我不解的是,为了在我的机子上是这样的,而在小甲鱼老师的机子上是很正常的输出了,都不用debug 2.exe的,直接在cmd下就可以。这个让我很是纠结!!!难道是我的机子“高级”了点?还有就是各位鱼友在你们的机子上是个什么情况啊?帮忙测试一下哈。。。诶,说到这个发帖也是让我头疼了一把,这么多字,我承认废话确实挺多,很高兴你能耐心的看到了这里。而且这号是新号,发贴的时候还不让帖图片,愣是让我弄了好久!不容易啊!本来看这么长的字了,不如直接写个日志吧,可因为我的等级太低,竟然连日志都不能写。。。。郁闷啊 。。。。强烈谴责小甲鱼,你不能这么鄙视新人吧,不能因为等级低就不能让人家不能写日志吧。。。。抗议,改革!

如果。。。 发表于 2012-8-18 22:18:19

占个沙发吧。。。{:1_1:}

lukelqz 发表于 2012-8-18 22:50:31

{:5_91:}顶一个

网络学习 发表于 2012-8-19 00:02:06

这是什么问题呢

如果。。。 发表于 2012-8-19 08:55:33

郁闷啊!!!!:Q:Q:Q:Q:Q:Q:Q:Q:Q:Q:Q

lukelqz 发表于 2012-8-19 09:49:09

本帖最后由 lukelqz 于 2012-8-19 09:59 编辑

{:5_95:}你的问题我已经找到了,关键就在于,自己改了原来的程序(值得提倡),但是却在里面犯了小问题。所以导致ds:si不能指向正确的字符串的首地址。
我们来分析一下,你的第27行代码
do0start: mov si,offset do0 + 2虽然在原来的安装程序中运行没有错误,但是复制到0:200h的地方就有问题了,他不能指向字符串的正确的首地址了。
我把你的安装程序编译运行后,debug图

看出来了,字符串存在了0:202的地方
然后再看看你的si指向了哪里

好吧,指飞了,所以,出现了乱码

so,给你的代码更改后:
mov si,202h ;设置si指向字符串
mov ax,cs            ;下面的这两步必须加上,否则你的DS不是0,那么自然也不是0:202了
mov ds,ax当然你也可以这么写
mov si,202h ;设置si指向字符串


mov ax,0b800h
mov es,ax
mov di,12*160+36*2 ;设置es:di指向显存空间的中间位置

mov cx,9 ;设置字符串长度cx
s: mov al,cs:   ;上面没有把cs的给ds,那么在的前面加上段前缀cs,这样也可以指向0:202hPS:0:200h-0:2ffh这256字节是王爽老师特意强调的安全空间,不要怀疑哦

如果。。。 发表于 2012-8-19 09:59:16

lukelqz 发表于 2012-8-19 09:49 static/image/common/back.gif
你的问题我已经找到了,关键就在于,自己改了原来的程序(值得提倡),但是却在里面犯了小问题。所 ...

嗯嗯!谢谢你啦!刚才照你说的给改回来了,然后再试了下,真的行了!
http://ww2.sinaimg.cn/mw690/92c7cb9bgw1dw1radkh30j.jpg
自作聪明的我以为改了那里把3句代码减为1句还暗暗得意呢!没想到这是个致命的错误!多亏了你发现了!!真的十分感谢!可是唯一的遗憾是,为什么必须要用debug 2.exe才可以看到呢,直接在cmd中运行就看不到。。。这个问题始终困扰着我。。。蛋疼。。。。。

lukelqz 发表于 2012-8-19 10:03:32

如果。。。 发表于 2012-8-19 09:59 static/image/common/back.gif
嗯嗯!谢谢你啦!刚才照你说的给改回来了,然后再试了下,真的行了!

自作聪明的我以为改了那里把3句代 ...

你的电脑问题,我的电脑也经常会这样,我的独门秘籍就是
进入debug一下,然后什么也不干,输入q键退出,窗口不要关,然后再直接运行刚刚不能显示的程序就好了,不用debug+g命令跳转也能显示。

如果。。。 发表于 2012-8-19 10:06:07

lukelqz 发表于 2012-8-19 10:03 static/image/common/back.gif
你的电脑问题,我的电脑也经常会这样,我的独门秘籍就是
进入debug一下,然后什么也不干,输入q键退出, ...

可是我这机不行。。。诶。。算了,以后就用dubug-g跳转吧!

lukelqz 发表于 2012-8-19 10:08:41

如果。。。 发表于 2012-8-19 10:06 static/image/common/back.gif
可是我这机不行。。。诶。。算了,以后就用dubug-g跳转吧!

{:5_103:}无能无力了,你试试运行command。在command窗口中运行看看,行不行。不是cmd哦。command是虚拟86模式,更贴近于dos实模式。cmd是保护模式,32位的。

Mushroom"_ 发表于 2012-8-20 00:25:54

:D学习咯~~
页: [1]
查看完整版本: 中断例程的一些小疑问..