鱼C论坛

 找回密码
 立即注册
查看: 3293|回复: 11

int 9 中断例程

[复制链接]
发表于 2017-2-7 18:37:44 | 显示全部楼层 |阅读模式

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

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

x
  1. ;编程:在屏幕中间依次显示“a”~“z”,并可以让人看清。
  2. ;在显示的过程中,按下“ESC”键后,改变显示的颜色。
  3. assume cs:code,ss:stack,ds:data

  4. data segment
  5.                         db 0,0,0,0
  6. data ends

  7. stack segment
  8.                         db 128 dup(0)
  9. stack ends

  10. code segment
  11. start:                 mov ax,data
  12.                         mov ds,ax
  13.                         mov ax,stack
  14.                         mov ss,ax
  15.                         mov sp,128
  16.                         mov ax,0
  17.                         mov es,ax                        ;中断向量表的段地址为0
  18.                
  19.                         push es:[9*4]                ;将原来 int 9 中断例程的指令的                       
  20.                         pop ds:[0]                        ;ip保存到ds:[0],cs保存到ds:[2]单元中
  21.                         push es:[9*4+2]
  22.                         pop ds:[2]
  23.                        
  24.                         mov word ptr es:[9*4],offset int9
  25.                         mov word ptr es:[9*4+2],cs        ;设置新的中断例程
  26.                        
  27.                        
  28.                         mov ax,0b800h
  29.                         mov es,ax
  30.                         mov si,160*12+40*2
  31.                         mov ah,'a'
  32.                        
  33. s:                        mov es:[si],ah
  34.                         call delay       
  35.                         inc ah
  36.                         cmp ah,'z'
  37.                         jna s
  38.                        
  39.                         mov ax,0                        ;中断例程的入口地址恢复为
  40.                         mov es,ax                        ;原来的入口地址
  41.                         push ds:[0]                       
  42.                         pop es:[9*4]
  43.                         push ds:[2]
  44.                         pop es:[9*4+2]

  45.                         mov ax,4c00h
  46.                         int 21h
  47.                        
  48. delay:          push ax
  49.                         push dx
  50.                        
  51.                         mov dx,1000h
  52.                         mov ax,0
  53.                        
  54. s1:                        sub ax,1
  55.                         sbb dx,0
  56.                         cmp ax,0
  57.                         jne s1
  58.                         cmp dx,0ff0h
  59.                         jne s1
  60.                        
  61.                         pop dx
  62.                         pop ax
  63.                         ret
  64. ;--------以下为新的 int 9 中断例程--------------------

  65. int9:                push ax
  66.                         push bx
  67.                         push es
  68.                         push si
  69.                        
  70.                         in al,60h                ;从60h端口读入数据
  71.                        
  72.                         pushf
  73.                         pop bx
  74.                         pushf
  75.                         and bx,1111110011111111b
  76.                         push bx
  77.                         popf
  78.                         call dword ptr ds:[0]        ;对int指令进行模拟,调用原来的int 9中断例程
  79.                        
  80.                         cmp al,1
  81.                         jne int9ret
  82.                        
  83.                         mov ax,0b800h
  84.                         mov es,ax
  85.                         inc byte ptr es:[si+1]         ;属性增加1,改变颜色

  86. int9ret:        pop si
  87.                         pop es
  88.                         pop bx
  89.                         pop ax
  90.                         iret
  91.                          
  92. code ends

  93. end start
复制代码


如图,程序在 mov word ptr [9*4],0ffset int9 位置处发生了错误,此后无法执行任何内容,呈死机状态。
QQ截图20170207183100.png
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-2-7 22:25:33 | 显示全部楼层
1.不要用debug单步调试,我复制书上的答案也不能用debug单步调试

2.程序延时太短

  1. ;编程:在屏幕中间依次显示“a”~“z”,并可以让人看清。
  2. ;在显示的过程中,按下“ESC”键后,改变显示的颜色。
  3. assume cs:code,ss:stack,ds:data

  4. data segment
  5.                         db 0,0,0,0
  6. data ends

  7. stack segment
  8.                         db 128 dup(0)
  9. stack ends

  10. code segment
  11. start:                 mov ax,data
  12.                         mov ds,ax
  13.                         mov ax,stack
  14.                         mov ss,ax
  15.                         mov sp,128
  16.                         mov ax,0
  17.                         mov es,ax                        ;中断向量表的段地址为0
  18.                
  19.                         push es:[9*4]                ;将原来 int 9 中断例程的指令的                        
  20.                         pop ds:[0]                        ;ip保存到ds:[0],cs保存到ds:[2]单元中
  21.                         push es:[9*4+2]
  22.                         pop ds:[2]
  23.                         
  24.                         mov word ptr es:[9*4],offset int9
  25.                         mov word ptr es:[9*4+2],cs        ;设置新的中断例程
  26.                         
  27.                         
  28.                         mov ax,0b800h
  29.                         mov es,ax
  30.                         mov si,160*12+40*2
  31.                         mov ah,'a'
  32.                         
  33. s:                        mov es:[si],ah
  34.                         call delay        
  35.                         inc ah
  36.                         cmp ah,'z'
  37.                         jna s
  38.                         
  39.                         mov ax,0                        ;中断例程的入口地址恢复为
  40.                         mov es,ax                        ;原来的入口地址
  41.                         push ds:[0]                        
  42.                         pop es:[9*4]
  43.                         push ds:[2]
  44.                         pop es:[9*4+2]

  45.                         mov ax,4c00h
  46.                         int 21h
  47.                         
  48. delay:          push ax
  49.                         push dx
  50.                         
  51.                         mov dx,1000h
  52.                         mov ax,0
  53.                         
  54. s1:                        sub ax,1
  55.                         sbb dx,0
  56.                         cmp ax,0
  57.                         jne s1
  58.                         ;cmp dx,0ff0h
  59.                         cmp dx,0
  60.                         jne s1
  61.                         
  62.                         pop dx
  63.                         pop ax
  64.                         ret
  65. ;--------以下为新的 int 9 中断例程--------------------

  66. int9:                push ax
  67.                         push bx
  68.                         push es
  69.                         push si
  70.                         
  71.                         in al,60h                ;从60h端口读入数据
  72.                         
  73.                         pushf
  74.                         pop bx
  75.                         pushf
  76.                         and bx,1111110011111111b
  77.                         push bx
  78.                         popf
  79.                         call dword ptr ds:[0]        ;对int指令进行模拟,调用原来的int 9中断例程
  80.                         
  81.                         cmp al,1
  82.                         jne int9ret
  83.                         
  84.                         mov ax,0b800h
  85.                         mov es,ax
  86.                         inc byte ptr es:[si+1]         ;属性增加1,改变颜色

  87. int9ret:        pop si
  88.                         pop es
  89.                         pop bx
  90.                         pop ax
  91.                         iret
  92.                         
  93. code ends

  94. end start
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-2-8 11:40:32 | 显示全部楼层
人造人 发表于 2017-2-7 22:25
1.不要用debug单步调试,我复制书上的答案也不能用debug单步调试

2.程序延时太短

那程序万一出错了,不能单步调试,看源程序又看不出来,那怎么办啊
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-2-8 11:43:26 | 显示全部楼层
Cy86183570 发表于 2017-2-8 11:40
那程序万一出错了,不能单步调试,看源程序又看不出来,那怎么办啊

这个我也没有什么好的办法,因为这个程序比较特殊,此程序正好使用了键盘中断
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-2-8 12:58:55 | 显示全部楼层
人造人 发表于 2017-2-8 11:43
这个我也没有什么好的办法,因为这个程序比较特殊,此程序正好使用了键盘中断

正头疼中,好像程序无法装入中断向量表中,调试也没办法调试,看程序又没什么问题,汇编可真是麻烦啊!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-2-8 13:25:37 | 显示全部楼层
Cy86183570 发表于 2017-2-8 12:58
正头疼中,好像程序无法装入中断向量表中,调试也没办法调试,看程序又没什么问题,汇编可真是麻烦啊!

你这个程序没有什么问题呀
就是延时有点少
试试这个
  1. ;编程:在屏幕中间依次显示“a”~“z”,并可以让人看清。
  2. ;在显示的过程中,按下“ESC”键后,改变显示的颜色。
  3. assume cs:code,ss:stack,ds:data

  4. data segment
  5.                         db 0,0,0,0
  6. data ends

  7. stack segment
  8.                         db 128 dup(0)
  9. stack ends

  10. code segment
  11. start:                 mov ax,data
  12.                         mov ds,ax
  13.                         mov ax,stack
  14.                         mov ss,ax
  15.                         mov sp,128
  16.                         mov ax,0
  17.                         mov es,ax                        ;中断向量表的段地址为0
  18.                
  19.                         push es:[9*4]                ;将原来 int 9 中断例程的指令的                        
  20.                         pop ds:[0]                        ;ip保存到ds:[0],cs保存到ds:[2]单元中
  21.                         push es:[9*4+2]
  22.                         pop ds:[2]
  23.                         
  24.                         mov word ptr es:[9*4],offset int9
  25.                         mov word ptr es:[9*4+2],cs        ;设置新的中断例程
  26.                         
  27.                         
  28.                         mov ax,0b800h
  29.                         mov es,ax
  30.                         mov si,160*12+40*2
  31.                         mov ah,'a'
  32.                         
  33. s:                        mov es:[si],ah
  34.                         call delay        
  35.                         inc ah
  36.                         cmp ah,'z'
  37.                         jna s
  38.                         
  39.                         mov ax,0                        ;中断例程的入口地址恢复为
  40.                         mov es,ax                        ;原来的入口地址
  41.                         push ds:[0]                        
  42.                         pop es:[9*4]
  43.                         push ds:[2]
  44.                         pop es:[9*4+2]

  45.                         mov ax,4c00h
  46.                         int 21h
  47.                         
  48. delay:          push ax
  49.                         push dx
  50.                         
  51.                         mov dx,1000h
  52.                         mov ax,0
  53.                         
  54. s1:                        sub ax,1
  55.                         sbb dx,0
  56.                         cmp ax,0
  57.                         jne s1
  58.                         ;cmp dx,0ff0h
  59.                         cmp dx,0
  60.                         jne s1
  61.                         
  62.                         pop dx
  63.                         pop ax
  64.                         ret
  65. ;--------以下为新的 int 9 中断例程--------------------

  66. int9:                push ax
  67.                         push bx
  68.                         push es
  69.                         push si
  70.                         
  71.                         in al,60h                ;从60h端口读入数据
  72.                         
  73.                         pushf
  74.                         pop bx
  75.                         pushf
  76.                         and bx,1111110011111111b
  77.                         push bx
  78.                         popf
  79.                         call dword ptr ds:[0]        ;对int指令进行模拟,调用原来的int 9中断例程
  80.                         
  81.                         cmp al,1
  82.                         jne int9ret
  83.                         
  84.                         mov ax,0b800h
  85.                         mov es,ax
  86.                         inc byte ptr es:[si+1]         ;属性增加1,改变颜色

  87. int9ret:        pop si
  88.                         pop es
  89.                         pop bx
  90.                         pop ax
  91.                         iret
  92.                         
  93. code ends

  94. end start
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-2-8 13:49:36 | 显示全部楼层
人造人 发表于 2017-2-8 13:25
你这个程序没有什么问题呀
就是延时有点少
试试这个

程序可以运行的,可是我把int 9中断例程的存放位置更改了,就运行不了了,大神,帮我看看
  1. ;编程:在屏幕中间依次显示“a”~“z”,并可以让人看清。
  2. ;在显示的过程中,按下“ESC”键后,改变显示的颜色。
  3. assume cs:code,ss:stack,ds:data

  4. data segment
  5.                         db 0,0,0,0
  6. data ends

  7. stack segment
  8.                         db 128 dup(0)
  9. stack ends

  10. code segment
  11. start:                 mov ax,stack
  12.                         mov ss,ax
  13.                         mov sp,128
  14.                         mov ax,0
  15.                         mov es,ax                        ;中断向量表的段地址为0
  16.                
  17.                         push es:[9*4]                ;将原来 int 9 中断例程的指令的                       
  18.                         pop es:[200h]
  19.                         push es:[9*4+2]                ;ip保存到0:200,cs保存到0:202
  20.                         pop es:[202h]
  21.                        
  22.                         mov ax,cs                        ;将新int 9中断例程的入口地址
  23.                         mov ds,ax
  24.                         mov si,offset int9
  25.                         mov di,204h
  26.                         mov cx,offset int9end - offset int9
  27.                        
  28.                         cld
  29.                         rep movsb                                               
  30.                        
  31.                         cli                                ;将IF置0,屏蔽其他可屏蔽的中断
  32.                         mov word ptr es:[9*4],204h                        ;设置新的中断例程
  33.                         mov word ptr es:[9*4+2],0
  34.                         sti                                ;恢复IF置1
  35.                        
  36.                         mov ax,0b800h
  37.                         mov es,ax
  38.                         mov ah,'a'
  39.                        
  40. s:                        mov es:[160*12+40*2],ah
  41.                         call delay       
  42.                         inc ah
  43.                         cmp ah,'z'
  44.                         jna s
  45.                        
  46.                         mov ax,0                        ;中断例程的入口地址恢复为
  47.                         mov es,ax                        ;原来的入口地址
  48.                         push es:[200h]                       
  49.                         pop es:[9*4]
  50.                         push es:[202h]
  51.                         pop es:[9*4+2]

  52.                         mov ax,4c00h
  53.                         int 21h
  54.                        
  55. delay:          push ax
  56.                         push dx
  57.                        
  58.                         mov dx,1000h
  59.                         mov ax,0
  60.                        
  61. s1:                        sub ax,1
  62.                         sbb dx,0
  63.                         cmp ax,0
  64.                         jne s1
  65.                         cmp dx,0ff0h
  66.                         jne s1
  67.                        
  68.                         pop dx
  69.                         pop ax
  70.                         ret
  71. ;--------以下为新的 int 9 中断例程--------------------

  72. int9:                push ax
  73.                         push bx
  74.                         push es
  75.                        
  76.                         in al,60h                ;从60h端口读入数据
  77.                        
  78.                         pushf
  79.                         pop bx
  80.                         pushf
  81.                         and bx,1111110011111111b
  82.                         push bx
  83.                         popf
  84.                         call dword ptr es:[200h]        ;对int指令进行模拟,调用原来的int 9中断例程
  85.                        
  86.                         cmp al,1+80h
  87.                         jne int9ret
  88.                        
  89.                         mov ax,0b800h
  90.                         mov es,ax
  91.                         inc byte ptr es:[160*12+40*2+1]         ;属性增加1,改变颜色

  92. int9ret:        pop es
  93.                         pop bx
  94.                         pop ax
  95.                         iret
  96. int9end:        nop         
  97. code ends

  98. end start
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-2-8 14:25:17 | 显示全部楼层
Cy86183570 发表于 2017-2-8 13:49
程序可以运行的,可是我把int 9中断例程的存放位置更改了,就运行不了了,大神,帮我看看
  1. ;编程:在屏幕中间依次显示“a”~“z”,并可以让人看清。
  2. ;在显示的过程中,按下“ESC”键后,改变显示的颜色。
  3. assume cs:code,ss:stack,ds:data

  4. data segment
  5.                         db 0,0,0,0
  6. data ends

  7. stack segment
  8.                         db 128 dup(0)
  9. stack ends

  10. code segment
  11. start:                 mov ax,stack
  12.                         mov ss,ax
  13.                         mov sp,128
  14.                         mov ax,0
  15.                         mov es,ax                        ;中断向量表的段地址为0
  16.                
  17.                         push es:[9*4]                ;将原来 int 9 中断例程的指令的                        
  18.                         pop es:[200h]
  19.                         push es:[9*4+2]                ;ip保存到0:200,cs保存到0:202
  20.                         pop es:[202h]
  21.                         
  22.                         mov ax,cs                        ;将新int 9中断例程的入口地址
  23.                         mov ds,ax
  24.                         mov si,offset int9
  25.                         mov di,204h
  26.                         mov cx,offset int9end - offset int9
  27.                         
  28.                         cld
  29.                         rep movsb                                                
  30.                         
  31.                         cli                                ;将IF置0,屏蔽其他可屏蔽的中断
  32.                         mov word ptr es:[9*4],204h                        ;设置新的中断例程
  33.                         mov word ptr es:[9*4+2],0
  34.                         sti                                ;恢复IF置1
  35.                         
  36.                         mov ax,0b800h
  37.                         mov es,ax
  38.                         mov ah,'a'
  39.                         
  40. s:                        mov es:[160*12+40*2],ah
  41.                         call delay        
  42.                         inc ah
  43.                         cmp ah,'z'
  44.                         jna s
  45.                         
  46.                         mov ax,0                        ;中断例程的入口地址恢复为
  47.                         mov es,ax                        ;原来的入口地址
  48.                         push es:[200h]                        
  49.                         pop es:[9*4]
  50.                         push es:[202h]
  51.                         pop es:[9*4+2]

  52.                         mov ax,4c00h
  53.                         int 21h
  54.                         
  55. delay:          push ax
  56.                         push dx
  57.                         
  58.                         mov dx,1000h
  59.                         mov ax,0
  60.                         
  61. s1:                        sub ax,1
  62.                         sbb dx,0
  63.                         cmp ax,0
  64.                         jne s1
  65.                         ;cmp dx,0ff0h
  66.                         cmp dx, 0 ; 都说了,你的延时太短
  67.                         jne s1
  68.                         
  69.                         pop dx
  70.                         pop ax
  71.                         ret
  72. ;--------以下为新的 int 9 中断例程--------------------

  73. int9:                push ax
  74.                         push bx
  75.                         push es
  76.                         
  77.                         ;这里
  78.                         mov ax, 0
  79.                         mov es, ax
  80.                        
  81.                         in al,60h                ;从60h端口读入数据
  82.                         
  83.                         pushf
  84.                         ;pop bx
  85.                         pushf
  86.                         pop bx ;这里
  87.                         and bx,1111110011111111b
  88.                         push bx
  89.                         popf
  90.                        

  91.                         call dword ptr es:[200h]        ;对int指令进行模拟,调用原来的int 9中断例程
  92.                         
  93.                         cmp al,1+80h
  94.                         jne int9ret
  95.                         
  96.                         mov ax,0b800h
  97.                         mov es,ax
  98.                         inc byte ptr es:[160*12+40*2+1]         ;属性增加1,改变颜色

  99. int9ret:        pop es
  100.                         pop bx
  101.                         pop ax
  102.                         iret
  103. int9end:        nop         
  104. code ends

  105. end start
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-2-8 14:44:13 | 显示全部楼层

后来我明白不是程序的问题,你说延时短,真没有问题,我不知道我电脑怎么回事,原来我设置的延时是跟视频里一样很长的,可惜只怪我电脑反映不过来,所以才设置短的,之后都没有问题,直到我改了int 9 中断例程的存储位置,也就是放到了0:204单元才显示不出来,我之后又重看了遍视频,寻找了一些以前别人的程序,才知道不是程序的问题,是必须在DOS实装模式下才能显示出来。抱歉了,费那么大劲,都是我自己没仔细看视频的锅。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-2-8 15:38:34 | 显示全部楼层
Cy86183570 发表于 2017-2-8 14:44
后来我明白不是程序的问题,你说延时短,真没有问题,我不知道我电脑怎么回事,原来我设置的延时是跟视频 ...

实模式?
下面gif如何解释
GIF.gif
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-2-8 16:07:34 | 显示全部楼层
人造人 发表于 2017-2-8 15:38
实模式?
下面gif如何解释

不是啦,没改int 9程序的存储地址,我也能显示出来的
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-2-8 17:15:40 | 显示全部楼层
Cy86183570 发表于 2017-2-8 16:07
不是啦,没改int 9程序的存储地址,我也能显示出来的

不明白你在说什么,不过问题解决了进行
^_^
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-7-12 17:10

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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