《汇编语言·第三版》--王爽
1 问题
安装一个新的int 9中断例程,功能:在DOS下,按下“A”键后,除非不再松开,如果松开,就显示满屏幕的“A”,其它的键照常处理。
提示,按下一个键时产生的扫描码称为通码,松开一个键产生的扫面码称为断码。断码 = 通码 + 80h。
2 分析
键盘输入到达60h端口后,就会引发9号中断,CPU则去执行int 9中断例程。
(1) 只检测“A”的断码
如果60h端口内的扫描码为“A”的断码,则满屏显示“A”。
(2) 满屏幕显示“A”
往B8000H开始的4000个字节中的偶地址内写A。
1. mov ax, 0b800h 2. mov es, ax 3. mov bx, 0 4. mov cx, 2000 5. i9s: mov byte ptr es:[bx], ‘A’ 6. add bx, 2 7. loop i9s |
(3) 其他键照常处理
调用原来的int 9中断处理程序,来处理其他的键盘输入。原来的int 9中断处理程序的入口地址在(4 * 9)字单元中。
(4) 新int 9中断例程的安装
中断程序可以在任意内存中,由于8086PC机中0000:0 ~ 0000:03FF是专门存放中断程序入口地址的内存区,且0000:0200 ~0000:02FF内存空间所对应的中断向量表是空的,操作系统也不占用这段空间,故而将中断程序拷贝到这段空间内。
3 代码
1. assume cs:code 2. 3. stack segment 4. db 128 dup(0) 5. stack ends 6. 7. code segment 8. start: 9. mov ax, stack 10. mov ss, ax 11. mov sp, 128 12. 13. push cs 14. pop ds 15. 16. ;-------安装程序到0:204-------- 17. mov ax, 0 18. mov es, ax 19. mov si, offset int9 ;ds:[si]指向int 9中断例程的起始处 20. mov di, 204h ;es:[di]为int 9程序安装起始位置 21. mov cx, offset int9end- offset int9 22. cld 23. rep movsb 24. ;-------安装程序到0:204-------- 25. 26. 27. ;-------保存int 9中断例程的入口地址到0:200 ~ 0:202四个字节处---------- 28. push es:[9 *4] ;原int 9中断例程的偏移地址 29. pop es:[200h] 30. push es:[9 * 4+ 2] ;原int 9中断例程的段地址 31. pop es:[202h] 32. ;-------保存int 9中断例程的入口地址到0:200 ~ 0:202四个字节处---------- 33. 34. 35. ;-------为新的int 9中断例程改写新的入口地址----------- 36. cli ;IF = 0,在改写9号中断类型码中断例程入口地址时不允许中断 37. mov word ptr es:[9 *4], 204h 38. mov word ptr es:[9 *4 + 2], 0 39. sti 40. ;-------为新的int 9中断例程改写新的入口地址----------- 41. 42. mov ax, 4c00h 43. int 21h 44. 45. ;int 9中断新例程 46. ;功能:按下“A”键后,除非不再松开, 47. ;如果松开,就显示满屏幕的“A”,其它的键照常处理。 48. ;参数:无 49. ;返回:无 50. int9: 51. push ax 52. push bx 53. push cx 54. push es 55. 56. in al,60h 57. pushf 58. call dword ptr cs:[200h] ;仿照int指令调用原来的int 9中断例程处理键盘输入 59. 60. cmp al, 1eh +80h ;比较是否为A键断码 61. jne int9ret 62. 63. ;--------满屏幕显示A------- 64. mov ax,0b800h 65. mov es, ax 66. mov bx, 0 67. mov cx, 2000 68. i9s: 69. mov byte ptr es:[bx], 'A' 70. add bx,2 71. loop i9s 72. ;--------满屏幕显示A------- 73. 74. int9ret: 75. pop es 76. pop cx 77. pop bx 78. pop ax 79. iret 80. 81. int9end:nop 82. 83. code ends 84. end start |