《汇编语言·第三版》--王爽
1 问题
安装一个新的int 7ch中断例程,为显示输出提供如下功能子程序。
(1) 清屏;
(2) 设置前景色;
(3) 设置背景色;
(4) 向上滚动一行。
入口参数说明如下。
(1) 用ah寄存器传递功能号;0表示清屏,1表示设置前景色,2表示设置背景色,3表示向上滚动一行。
(2) 对于1、2号功能,用al传送颜色值,(al) 属于{0, 1, 2, 3, 4, 5, 6, 7}。
2 分析
(1) int 7ch中断例程安装位置
用程序拷贝程序将int 7ch中断例程拷贝到0:200起始位置处。
(2) 多功能子程序实现
用直接定址表实现多功能子程序的实现。
(3) 测试程序
额外写4个汇编程序测试int 7ch中断例程。
3 代码
(1) 安装程序
1. assume cs:code 2. 3. code segment 4. start: 5. ;--------拷贝i7ch 中断例程到0:200h起始内存处-------- 6. mov ax, cs 7. mov ds, ax 8. mov si, offset i7cstart 9. 10. mov ax, 0 11. mov es, ax 12. mov di,200h 13. 14. mov cx, offset i7cend -offset i7cstart 15. cld 16. rep movsb 17. ;--------拷贝i7ch 中断例程到0:200h起始内存处-------- 18. 19. ;--------改写7ch中断向量表中的入口地址------- 20. mov ax, 0 21. mov es, ax 22. mov word ptr es:[7ch* 4], 200h 23. mov word ptr es:[7ch* 4 + 2], 0 24. ;--------改写7ch中断向量表中的入口地址------- 25. 26. 27. mov ax, 4c00h 28. int 21h 29. 30. org 200h 31. ;伪指令,表示下一条指令从偏移地址200H开始,正好和安装后的偏移地址相同 32. ;因为如果没有ORG 200H,此中断例程被安装以后,标号所代表的地址变了,和之前编译器编译的有别 33. 34. ;int 7ch中断例程 35. ;功能:见问题 36. ;参数:见问题 37. ;返回:无 38. i7cstart: 39. setscreen: jmp short set 40. table dw clear, setf, setbk, rollup 41. 42. set: 43. push bx 44. 45. cmp ah,3 46. ja sret 47. mov bl,ah 48. mov bh,0 49. add bx,bx ;得到子函数dw类型下标值 50. 51. call word ptr table[bx] 52. sret: 53. pop bx 54. iret 55. 56. ;功能:清屏 57. ;参数:无 58. ;返回值:无 59. clear: 60. push bx 61. push cx 62. push es 63. 64. mov bx,0b800h 65. mov es,bx 66. mov bx,0 67. mov cx,2000 68. clear_s: 69. mov byte ptr es:[bx],' ' 70. add bx, 2 71. loop clear_s 72. pop es 73. pop cx 74. pop bx 75. ret 76. 77. ;功能:设置前景色 78. ;参数al表前景色 79. ;返回值:无 80. setf: 81. push bx 82. push cx 83. push es 84. 85. mov bx,0b800h 86. mov es,bx 87. mov bx,1 88. mov cx,2000 89. 90. setf_s: 91. and byte ptr es:[bx], 11111000b 92. or es:[bx], al 93. add bx, 2 94. loop setf_s 95. 96. pop es 97. pop cx 98. pop bx 99. ret 100. 101. ;功能:设置背景色 102. ;参数al表背景色 103. ;返回值:无 104. setbk: 105. push bx 106. push cx 107. push es 108. 109. mov bx, 0b800h 110. mov es, bx 111. mov bx, 1 112. mov cx, 2000 113. 114. setbk_s: 115. and byte ptr es:[bx], 10001111b 116. or es:[bx], al 117. add bx, 2 118. loop setbk_s 119. 120. pop es 121. pop cx 122. pop bx 123. ret 124. 125. ;功能:屏幕往上滚动一行 126. ;参数:无 127. ;返回值:无 128. rollup: 129. push cx 130. push si 131. push di 132. push es 133. push ds 134. 135. mov si, 0b800h 136. mov es, si 137. mov ds, si 138. mov si, 160 ;ds:[si]第 n + 1行 139. mov di, 0 ;es:[di]第n行 140. mov cx, 24 141. cld 142. 143. rollup_s1: 144. push cx 145. mov cx, 160 146. rep movsb 147. pop cx ;拷贝完1行 148. loop rollup_s1 149. 150. mov cx, 80 151. mov si, 0 152. rollup_s2: 153. mov byte ptr [160 * 24 + si], ' ' 154. add si, 2 155. loop rollup_s2 156. 157. pop ds 158. pop es 159. pop di 160. pop si 161. pop cx 162. ret 163. i7cend: nop 164. code ends 165. end start |
(2) 测试程序
1. assume cs:code 2. 3. code segment 4. start: 5. mov ax,0h 6. int 7ch 7. 8. mov ax, 4c00h 9. int 21h 10. 11. code ends 12. end start |
Table2. test1.asm
1. assume cs:code 2. 3. code segment 4. start: 5. mov ax,0102h 6. int 7ch 7. 8. mov ax, 4c00h 9. int 21h 10. 11. code ends 12. end start |
Table3. test2.asm
1. assume cs:code 2. 3. code segment 4. start: 5. mov ax,0240h 6. int 7ch 7. 8. mov ax, 4c00h 9. int 21h 10. 11. code ends 12. end start |
Table4. test3.asm
1. assume cs:code 2. 3. code segment 4. start: 5. mov ax,0300h 6. int 7ch 7. 8. mov ax, 4c00h 9. int 21h 10. 11. code ends 12. end start |
4 调试
先编译连接并运行安装程序,然后再依次运行test1.asm、test2.asm、test3.asm、test0.asm对应的可执行程序。