鱼C论坛

 找回密码
 立即注册
查看: 6027|回复: 41

[汇编作业] 实验15 安装新的int9中断例程 及其 切换颜色程序的问题

[复制链接]
发表于 2017-6-9 23:13:55 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
实验15 安装新的int9中断例程 及其 切换颜色程序的问题
为什么我在虚拟机敲了两三遍还是没有预想的结果,一个代码是pdf上的源码,一个是答案的源码。执行后,什么效果都没有。谁能告诉我该如何解决?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-6-9 23:19:45 | 显示全部楼层
难道我太小白了吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-6-10 01:34:11 | 显示全部楼层
截图
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-6-10 09:25:42 | 显示全部楼层
QQ图片20170610092445.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-6-10 09:28:56 | 显示全部楼层

QQ图片20170610092445.png
又忘记如何回复贴了,第二次了。。。图已附上
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-6-10 09:35:47 | 显示全部楼层
本帖最后由 kyowjw01 于 2017-6-10 09:39 编辑


截的图中的代码是 王爽《汇编语言》第二版习题答案的实验15中的代码。不过这参考答案不一定会准确,因为检测点15.1(2)的答案就有问题,矫正后才会有效果。不过《汇编语言》(第三版)的pdf 15.5和这个实验15参考代码都没有效果,应该没这么邪门吧!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-6-10 11:51:26 | 显示全部楼层
kyowjw01 发表于 2017-6-10 09:35
截的图中的代码是 王爽《汇编语言》第二版习题答案的实验15中的代码。不过这参考答案不一定会准确,因 ...

还要发代码,不然,我就需要一个字母一个字母的从图片上抄了^_^
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-6-10 14:46:53 | 显示全部楼层
人造人 发表于 2017-6-10 11:51
还要发代码,不然,我就需要一个字母一个字母的从图片上抄了^_^

;任务:安装一个新的int 9中断例程

;功能:在DOS下,按'A'键后除非不再松开,如果松开,就显示满屏幕的'A',其他键照常处理

assume cs:code

stack segment

     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     ;设置ds:si指向源地址

     mov di,204h            ;设置es:di指向目标地址

     mov cx,offset int9end-offset int9    ;设置cx为传输长度

     cld                ;设置传输方向为正

     rep movsb

;将原来的int 9中断例程的入口地址保存在ds:200、ds:202单元中

     push es:[9*4]

     pop es:[200h]

     push es:[9*4+2]

     pop es:[202h]

;在中断向量表中设置新的int 9中断例程的入口地址

     cli                ;设置IF=0屏蔽中断

     mov word ptr es:[9*4],204h

     mov word ptr es:[9*4+2],0

     sti                ;设置IF=1不屏蔽中断

;结束

     mov ax,4c00h

     int 21h

;新的int 9中断例程

int9:    push ax

     push bx

     push cx

     push es

     in al,60h          ;从端口60h读出键盘输入

;对int指令进行模拟,调用原来的int 9中断例程

     pushf                  ;标志寄存器入栈

     call dword ptr cs:[200h]    ;CS,IP入栈,(IP)=cs:[200h],(CS)=0

;如果是A断码,改变当前屏幕的显示字符

     cmp al,9eh             ;和A的断码(1eh+80h)比较

     jne int9ret            ;不等于A时转移

     mov ax,0b800h

     mov es,ax

     mov bx,0

     mov cx,2000

s:   mov byte ptr es:[bx],41h    ;将A的ASCII码写入,改变字符

     add bx,2

     loop s

int9ret:pop es

     pop cx

     pop bx

     pop ax

     iret

int9end:nop

code ends

end start
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-6-10 15:41:25 | 显示全部楼层
kyowjw01 发表于 2017-6-10 14:46
;任务:安装一个新的int 9中断例程

;功能:在DOS下,按'A'键后除非不再松开,如果松开,就显示满屏幕 ...

你的程序没有问题
我再说一遍,你的程序没有问题,只是格式不好
我修改了一下

;任务:安装一个新的int 9中断例程
;功能:在DOS下,按'A'键后除非不再松开,如果松开,就显示满屏幕的'A',其他键照常处理
assume cs:code

stack segment
     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        ;设置ds:si指向源地址
        mov di, 204h                ;设置es:di指向目标地址
        mov cx, offset int9end - offset int9        ;设置cx为传输长度

        cld                ;设置传输方向为正
        rep movsb

        ;将原来的int 9中断例程的入口地址保存在ds:200、ds:202单元中
        push es:[9 * 4]
        pop es:[200h]
        push es:[9 * 4 + 2]
        pop es:[202h]

        ;在中断向量表中设置新的int 9中断例程的入口地址
        cli                ;设置IF=0屏蔽中断
        mov word ptr es:[9 * 4], 204h
        mov word ptr es:[9 * 4 + 2], 0
        sti                ;设置IF=1不屏蔽中断

        ;结束
        mov ax, 4c00h
        int 21h

        
;新的int 9中断例程
int9:
        push ax
        push bx
        push cx
        push es

        in al, 60h        ;从端口60h读出键盘输入

        ;对int指令进行模拟,调用原来的int 9中断例程
        pushf                ;标志寄存器入栈
        call dword ptr cs:[200h]        ;CS,IP入栈,(IP)=cs:[200h],(CS)=0

        ;如果是A断码,改变当前屏幕的显示字符
        cmp al, 1eh + 80h                ;和A的断码(1eh+80h)比较
        jne int9ret                ;不等于A时转移

        mov ax, 0b800h
        mov es, ax
        mov bx, 0
        mov cx, 2000
s:
        mov byte ptr es:[bx], 'A'        ;将A的ASCII码写入,改变字符
        add bx, 2
        loop s

int9ret:
        pop es
        pop cx
        pop bx
        pop ax
        iret

int9end:
        nop

code ends
end start


我在纯DOS下试了,可以
GIF.gif

在Windows 下cmd 应该没有调用 int9,所以看不到效果,使用debug查看
GIF1.gif
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-6-10 16:21:40 | 显示全部楼层
人造人 发表于 2017-6-10 15:41
你的程序没有问题
我再说一遍,你的程序没有问题,只是格式不好
我修改了一下

请教一下如何纯DOS,像你这样子的。我用的是虚拟机XP(x86)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-6-10 16:38:32 | 显示全部楼层
人造人 发表于 2017-6-10 15:41
你的程序没有问题
我再说一遍,你的程序没有问题,只是格式不好
我修改了一下

出来了,谢谢,像你第二张用debug可以
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-6-10 16:39:17 | 显示全部楼层
人造人 发表于 2017-6-10 15:41
你的程序没有问题
我再说一遍,你的程序没有问题,只是格式不好
我修改了一下

我现在的疑问是不知道怎么进入纯dos,应该不是alt+enter全屏吧?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-6-10 19:20:53 | 显示全部楼层
kyowjw01 发表于 2017-6-10 16:39
我现在的疑问是不知道怎么进入纯dos,应该不是alt+enter全屏吧?

在虚拟机中安装一个DOS系统
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-6-10 20:00:16 | 显示全部楼层
人造人 发表于 2017-6-10 19:20
在虚拟机中安装一个DOS系统

但我不知道怎么共享文件=。=|||,也不知道怎么把编译器丢进去
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-6-10 20:05:29 | 显示全部楼层
kyowjw01 发表于 2017-6-10 20:00
但我不知道怎么共享文件=。=|||,也不知道怎么把编译器丢进去

无标题.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-6-12 10:40:08 | 显示全部楼层
本帖最后由 kyowjw01 于 2017-6-12 11:02 编辑

assume cs:code

stack segment
 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                                        ;设置ds:si指向源地址
                mov di,204h                                                        ;设置es:di指向目的地址
                mov cx,offset int9end-offset int9        ;设置cx为传输长度
                cld                                                                        ;设置传输方向为正
                rep movsb
;将原来的int 9中断例程的入口地址保存在ds:200、ds:202单元中
                push es:[9*4]
                pop es:[200h]
                push es:[9*4+2]
                pop es:[202h]
;在中断向量表中设置新的int 9中断例程的入口地址
                cli                ;设置IF=0屏蔽中断
                mov word ptr es:[9*4],204h
                mov word ptr es:[9*4+2],0
                sti                ;设置IF=1不屏蔽中断
;结束
                mov ax,4c00h
                int 21h
;新的int 9中断例程
 int9:        
                push ax
                push bx
                push cx
                push es
                
                in al,60h                                        ;从端口60h读出键盘输入
;对int指令进行模拟,调用原来的int 9中断例程
                pushf                                                ;标志寄存器入栈
                call dword ptr cs:[200h]        ;CS,IP入栈,(IP)=cs:[200h],当此中断例程执行时(CS)=0
;如果是A断码,改变当前屏幕的显示字符
                cmp al,3bh                                        ;F1的扫描码为3bh
                jne int9ret                                        ;不等于扫描码(断码)时转移
                
                mov ax,0b800h
                mov es,ax
                mov bx,1                                        ;奇数为颜色
                mov cx,2000
        s:                                                        ;[b]不知道为何,如果这边不打回车,就出不来效果。[/b]
                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

花了一个多小时,才知道在代码段的标号s处(56行)打回车才出效果。
但是,我还是不知道为什么在代码段的标号s处(56行)中不打回车换行就不会出现变色效果?


想传图,但是点击发送,不小心点了撤销,提示说发图上限了。。。

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

使用道具 举报

 楼主| 发表于 2017-6-12 10:44:09 | 显示全部楼层

这个是F1切换整个颜色的代码。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-6-12 11:33:11 | 显示全部楼层

上图!

在标号S中不打回车换行,debug会卡死

在标号S中不打回车换行,debug会卡死

模拟的中断出现的效果图

模拟的中断出现的效果图
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-6-12 12:38:56 | 显示全部楼层

这个和换行没有关系
关了cmd,重新开一下
一个cmd只能执行一次这个程序,你说这是为什么呢?仔细看程序,你会知道答案的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-6-12 14:07:50 | 显示全部楼层
人造人 发表于 2017-6-12 12:38
这个和换行没有关系
关了cmd,重新开一下
一个cmd只能执行一次这个程序,你说这是为什么呢?仔细看程序 ...

又看了一遍,还是不明白。现在只知道一个cmd只能执行一次这个程序。因为是模拟的中断?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-10-6 12:28

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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