鱼C论坛

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

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

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

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

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

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

使用道具 举报

 楼主| 发表于 2017-6-9 23:19:45 | 显示全部楼层
难道我太小白了吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-6-10 01:34:11 | 显示全部楼层
截图
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2017-6-10 09:25:42 | 显示全部楼层
QQ图片20170610092445.png
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

QQ图片20170610092445.png
又忘记如何回复贴了,第二次了。。。图已附上
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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


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

使用道具 举报

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

还要发代码,不然,我就需要一个字母一个字母的从图片上抄了^_^
小甲鱼最新课程 -> https://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
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

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


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

  4. stack segment
  5.      db 128 dup (0)
  6. stack ends

  7. code segment

  8. start:
  9.         mov ax, stack
  10.         mov ss, ax
  11.         mov sp, 128

  12.         push cs
  13.         pop ds

  14.         mov ax, 0
  15.         mov es, ax
  16.         mov si, offset int9        ;设置ds:si指向源地址
  17.         mov di, 204h                ;设置es:di指向目标地址
  18.         mov cx, offset int9end - offset int9        ;设置cx为传输长度

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

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

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

  31.         ;结束
  32.         mov ax, 4c00h
  33.         int 21h

  34.        
  35. ;新的int 9中断例程
  36. int9:
  37.         push ax
  38.         push bx
  39.         push cx
  40.         push es

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

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

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

  48.         mov ax, 0b800h
  49.         mov es, ax
  50.         mov bx, 0
  51.         mov cx, 2000
  52. s:
  53.         mov byte ptr es:[bx], 'A'        ;将A的ASCII码写入,改变字符
  54.         add bx, 2
  55.         loop s

  56. int9ret:
  57.         pop es
  58.         pop cx
  59.         pop bx
  60.         pop ax
  61.         iret

  62. int9end:
  63.         nop

  64. code ends
  65. end start
复制代码



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

在Windows 下cmd 应该没有调用 int9,所以看不到效果,使用debug查看
GIF1.gif
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

请教一下如何纯DOS,像你这样子的。我用的是虚拟机XP(x86)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

出来了,谢谢,像你第二张用debug可以
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

我现在的疑问是不知道怎么进入纯dos,应该不是alt+enter全屏吧?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

在虚拟机中安装一个DOS系统
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

但我不知道怎么共享文件=。=|||,也不知道怎么把编译器丢进去
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

无标题.png
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

  1. assume cs:code

  2. stack segment
  3. db 128 dup (0)
  4. stack ends

  5. code segment
  6. start:       
  7.                 mov ax,stack
  8.                 mov ss,ax
  9.                 mov sp,128
  10.                
  11.                 push cs
  12.                 pop ds
  13.                
  14.                 mov ax,0
  15.                 mov es,ax
  16.                
  17.                 mov si,offset int9                                        ;设置ds:si指向源地址
  18.                 mov di,204h                                                        ;设置es:di指向目的地址
  19.                 mov cx,offset int9end-offset int9        ;设置cx为传输长度
  20.                 cld                                                                        ;设置传输方向为正
  21.                 rep movsb
  22. ;将原来的int 9中断例程的入口地址保存在ds:200、ds:202单元中
  23.                 push es:[9*4]
  24.                 pop es:[200h]
  25.                 push es:[9*4+2]
  26.                 pop es:[202h]
  27. ;在中断向量表中设置新的int 9中断例程的入口地址
  28.                 cli                ;设置IF=0屏蔽中断
  29.                 mov word ptr es:[9*4],204h
  30.                 mov word ptr es:[9*4+2],0
  31.                 sti                ;设置IF=1不屏蔽中断
  32. ;结束
  33.                 mov ax,4c00h
  34.                 int 21h
  35. ;新的int 9中断例程
  36. int9:       
  37.                 push ax
  38.                 push bx
  39.                 push cx
  40.                 push es
  41.                
  42.                 in al,60h                                        ;从端口60h读出键盘输入
  43. ;对int指令进行模拟,调用原来的int 9中断例程
  44.                 pushf                                                ;标志寄存器入栈
  45.                 call dword ptr cs:[200h]        ;CS,IP入栈,(IP)=cs:[200h],当此中断例程执行时(CS)=0
  46. ;如果是A断码,改变当前屏幕的显示字符
  47.                 cmp al,3bh                                        ;F1的扫描码为3bh
  48.                 jne int9ret                                        ;不等于扫描码(断码)时转移
  49.                
  50.                 mov ax,0b800h
  51.                 mov es,ax
  52.                 mov bx,1                                        ;奇数为颜色
  53.                 mov cx,2000
  54.         s:                                                        ;[color=Red][b]不知道为何,如果这边不打回车,就出不来效果。[/b][/color]
  55.                 inc byte ptr es:[bx]
  56.                 add bx,2
  57.                 loop s
  58.                
  59. int9ret:
  60.                 pop es
  61.                 pop cx
  62.                 pop bx
  63.                 pop ax
  64.                 iret
  65.                
  66. int9end:nop

  67. code ends
  68. end start
复制代码


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


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

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

这个是F1切换整个颜色的代码。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

上图!

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

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

模拟的中断出现的效果图

模拟的中断出现的效果图
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

使用道具 举报

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

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-7-1 13:22

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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