参考答案
实验内容
安装一个新的 int 9 中断例程,功能:在 DOS 下,按下"A"键后,除非不再松开,如果松开,就显示满屏幕的"A",其他的键照常处理。
提示:按下一个键时产生的扫描码称为通码,松开一个键产生的扫描码称为断码。断码=通码+80h
实验分析
使用老套路:
1)旧中断例程地址复制到别处,设置新中断例程地址。
2)新中断例程调用旧中断例程,另外如果是 A 的断码,就写入显存全变 A
汇编实现
assume cs:codeseg codeseg segment ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 新的中断程序 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; print_aaa: push ax push ds push si push cx ; 执行原有中断例程,其他的键照常处理 pushf call dword ptr cs:[0200H] in al, 60H ; 读取键盘扫描码 cmp al, 80H + 1EH ; 判断是否为 A 的断码 jne print_aaa_iret ; 如果不是 A 的断码,则返回 ; 向显存写入 A,我们只写入第一页 mov ax, 0B800H mov ds, ax mov si, 0 mov cx, 80 * 25 ; 只写入第一页,= 80 * 2 * 25 / 2 loop_s0: mov byte ptr ds:[si], 'A' add si, 2 loop loop_s0 print_aaa_iret: pop cx pop si pop ds pop ax iret print_aaa_end: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 复制中断程序 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; start: mov ax, cs ; 设置起始地址 mov ds, ax mov si, offset print_aaa mov ax, 0000H ; 设置目的地址 mov es, ax mov di, 0204H mov cx, offset print_aaa_end - offset print_aaa cld rep movsb ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; 设置中断向量表 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov ax, 0 mov es, ax ; 复制旧地址到 0000:0200 处 ; push es:[9 * 4] ; IP pop es:[0200H] ; IP push es:[9 * 4 + 2] ; CS pop es:[0202H] ; CS ; 设置新地址 cli mov word ptr es:[9 * 4], 0204H mov word ptr es:[9 * 4 + 2], 0 sti mov ax, 4C00H int 21H codeseg ends end start
附加说明
有个地方我一直还没弄明白:在 debug 中与在 debug 外,有什么区别。有这么个现象:
1)执行上述程序,安装中断例程。在程序运行结束后,再次返回终端,显示提示符(C:\>);
2)此时按 A 键,不会显示满屏的 A 字符;
3)当我们执行 debug any.exe 进入调试模式时,此时按 A 键,会显示满屏的 A 字符;
相关文章
「汇编语言 第 3 版 王爽」- 参考答案:实验 7 寻址方式在结构化数据访问中的应用
「汇编语言 第 3 版 王爽」- 参考答案:实验 16 编写包含多个功能子程序的中断例程
「汇编语言 第 3 版 王爽」- 参考答案:实验 14 访问 CMOS RAM
「汇编语言 第 3 版 王爽」- 参考答案:检测点 11.2
「汇编语言 第 3 版 王爽」- 参考答案:检测点 13.1
「汇编语言 第 3 版 王爽」- 参考答案:检测点 16.2
「汇编语言 第 3 版 王爽」- 参考答案:实验 13 编写、应用中断例程
「汇编语言 第 3 版 王爽」- 参考答案:检测点 11.3
「汇编语言 第 3 版 王爽」- 参考答案:实验 17 编写包含多个功能子程序的中断例程
「汇编语言 第 3 版 王爽」- 参考答案:课程设计 1
「汇编语言 第 3 版 王爽」- 参考答案:实验 11 编写子程序
「汇编语言 第 3 版 王爽」- 参考答案:实验 10 编写子程序
「汇编语言 第 3 版 王爽」- 参考答案:检测点 14.1
「汇编语言 第 3 版 王爽」- 参考答案:实验 12 编写 0 号中断的处理程序