目录 上一页 下一页 下一章

第3章 中断调用与子程序 -41-

  "MicroSoft"还是很重视这个对手的,因此在DOS中特意保留了CP/M的特征,以便于和CP/M-86兼容且易于将那些为CP/M编写的应用程序移植到DOS中。由此便有了这个"CD 20",也就有了前面的"RET之谜"。
  讲到此我们对CALL/RET可以说已经有较完整的印象了。不过以上对这两条指令的讨论还是很粗浅的,这里面还有更多的滋味我们还没有尝到,还需要更细致地加以咀嚼。
3.4 细致的咀嚼
  上一节给出了CALL指令的一种用法,这是很不全面的。这一节我们将"品尝"几个新程序,同时要"吃"出CALL指令更多的营养。请看下面的这个程序:
PROG4-B
-u100 12a[Enter]
0A3E:0100 B401
0A3E:0102 CD21
0A3E:0104 9A1F01220A
0A3E:0109 3C1B
0A3E:010B 75F3
0A3E:010D CD20
0A3E:010F 50
0A3E:0110 88C6
0A3E:0112 B780
0A3E:0114 B90800
0A3E:0117 88F3
0A3E:0119 B230
0A3E:011B 20FB
0A3E:011D 7402
0A3E:011F B231
0A3E:0121 B402
0A3E:0123 CD21
0A3E:0125 D0EF
0A3E:0127 E2EE
0A3E:0129 58
0A3E:012A CB
MOV
INT
CALL
CMP
JNZ
INT
PUSH
MOV
MOV
MOV
MOV
MOV
AND
JZ
MOV
MOV
INT
SHR
LOOP
POP
RETF
AH,01
21
0A3D:011F
AL,1B
0100
20
AX
DH,AL
BH,80
CX,0008
BL,DH
DL,30
BL,BH
0121
DL,31
AH,02
21
BH,1
0117
AX

;选择DOS API的01功能
;调用21H中断等待键盘输入
;调用0A3D:011F处的子程序
;输入的字符是"ESC"吗?
;不是"ESC"则转至0100H
;是"ESC"则结束程序
;子程序开始,保存AX寄存器副本
;输入字符的ASCII码置入DH寄存器
;BH寄存器置入"掩膜"10000000B
;处理8个数位
;BL寄存器置入输入字符的ASCII码
;DL寄存器置入字符0的ASCII码30H
;将ASCII码与"掩模"相与
;若结果为0,转至0121显示字符0
;将字符1的ASCII码置入DL寄存器
;选择DOS API的02H功能
;显示DL寄存器中的字符
;"掩模"向右移动一位
;循环至0117处理Bit6位
;恢复AX寄存器的原值
;返回主程序
  我们以"U"的形式给出这个程序,此程序没有存盘的必要。不过请大家务必注意不要原封不动地打入CALL指令后给出的"段:偏移"逻辑地址,因为在不同的机器上需要输入不同的段地址。段地址计算很简单,只需将CS中的实际段地址减1即可。输入程序后我们用"P"命令跟踪:

Copyright © 2004-2015 Reanimator www.cookmoon.org

目录 上一页 下一页 下一章