一、返回DOS操作系统
- 返回DOS的三种方法
程序框架设定的方法返回。将主程序定义为一个远过程,再执行三条指令,将DS和00H入堆栈,然后执行RET指令,转去执行INT20H,退出应用指令,释放所占内存,正确返回DOS。 - 执行4CH号DOS功能调用。
MOV AX,4C00H
INT 21H
利用这两条语句,在退出应用程序前,自动关闭已打开的文件,防止数据丢失。
3. 对于可执行的命令文件(.COM文件),用INT 20H可以直接返回DOS
二、DOS系统功能调用
DOS(Disk Operating System)是微软开发的磁盘操作系统,DOS从磁盘装入内存并运行。Windows问世后,DOS核心依然存在,只是加上了Windows作为系统的图形界面,使用户能更加方便地使用计算机。
其中,DOS的主要模块及其功能见P129(周荷琴 微机原理及接口技术)
8086CPU可以处理256类中断,利用INT n指令,原则上可调用这所有的中断。n 为中断类型号
n=00~FFH
00~04H—— 专用中断,处理 除法错、单步、不可屏蔽中断NMI、断电中断、溢出中断。
10H~1AH、2FH、31H、33H——BIOS(Basic Input and Output System)中断,基本输入输出系统。保存在系统ROM BIOS中的BIOS功能调用。
20H~2EH——DOS中断,对各种设备提供输入输出服务。INT 20H 程序结束中断,可返回DOS操作系统。n = 21H 是最强大的DOS中断,包含了很多子功能,每个有一个功能号,调用前要送到AH寄存器中。
INT 21H下的功能号部分举例:
1. 01H——从键盘输入一个字符,并在屏幕上显示,检查Ctrl-Break(若用户键入此键,则执行INT 23H,执行退出命令。) AL = 输入字符
2. 0AH——输入字符串到内存缓冲区;DS:DX = 缓冲区首地址
DATA SEGMENT
BUFF DB 50 ;定义缓存区,50个字节大小(32H)
DB ? ;存入实际键入字节数
DB 50 DUP(?) ;定义50个字节空间,存放键入字符的ASCII码
DATA ENDS
CODE SEGMENT
MOV AX,DATA
MOV DS,AX ;缓冲区首地址和偏移地址
MOV DX,OFFSET BUFF
MOV AH,0AH
INT 21H
CODE ENDS
3 . 显示功能调用
02H——显示单个字符,DL = 显示字符的ASCII码
09H——显示以$结尾的字符串,DS:DX = 字符串的首地址
DATA SEGMENT
MESS DB 'Try again.', 0DH,0AH,'$' ;0DH是回车,OAH是换行
DATA ENDS
CODE SEGMENT
MOV AX,SEG MESS
MOV DS,AX
MOV DX, OFFSET MESS
MOV AH,9
INT 21H
CODE ENDS
END
一些程序实例:
1. 键盘输入0~9,查表输出键入数字的平方值,存入AL寄存器中。
DATA SEGMENT
TABLE DB 0,1,4,9,16,25,36,49,64,81
BUF DB 'Please input a number(0~9):',0DH,0AH,'$'
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA
START:MOV AX,DATA
MOV DS,AX
MOV DX,OFFSET BUF
MOV AH,9H ;DOS 9号功能调用,显示提示信息
INT 21H
MOV AH,01
INT 21H
AND AL,0FH ;截下数字值,表内元素序号
MOV BX,OFFSET TABLE
MOV AH,0
ADD BX,AX ;表头地址+键入数字,结果存入BX
MOV AL,[BX] ;查表求得平方值
MOV AX,4C00H
INT 21H
CODE ENDS
END START
- 在存储单元A1和A2中,各存有一个2字节无符号数,低字节在前,高字节灾后,编程将两数相加,结果存入SUM单元,也要求低字节在前,高字节灾后,进位存入最后一个字节单元。
DATA SEGMENT
A1 DB 56H,78H
A2 DB 4FH,9AH
SUM DB 3 DUP(0)
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
BEGIN:MOV AX,DATA
MOV DS,AX ;设置数据地址段基址
MOV BX,0 ;BX为地址指针,清0
CLC ;进位清0
MOV AL,A1 [BX];取A1低字节
ADC AL,A2 [BX]
MOV SUM[BX],AL;低字节存入SUM中
INC BX ;调整指针
MOV AL,A1[BX]
ADC AL,A2[BX]
MOV SUM[BX],AL
JNC STOP ;无进位,转STOP
INC BX
MOV AL,0
INC AL
MOV SUM[BX],AL ;把进位存入SUM+2单元中
STOP:MOV AX,4C00H
INT 21H
CODE ENDS
END BEGIN
- 在存首地址储器中以BUF开始存有一串字符,字符串个数用COUNT表示。要求统计数字0~9、字母A~Z和其他字符的个数,并分别将它们的个数存储到NUM开始的3个内存单元中去。
DATA SEGMENT
BUF DB 'PRINT','abc',35H,52H,30H,08H
COUNT EQU $-BUF
NUM DB 3 DUP(?)
DATA ENDS
CODE SGEMENT
ASSUME CS:CODE,DS:DATA
START:MOV AX,DATA
MOV DS,AX
MOV CH,COUNT
MOV BX,0
MOV DX,0
LOOP1:MOV AH,BUF[BX]
CMP AH,30H
JL NEXT
CMP AH,39H
JG ABC
INC DH
JMP NEXT
ABC:CMP AH,41H
JL NEXT
CMP AH,5AH
JG NEXT
INC DL
NEXT:INC BX
DEC CH
JNZ LOOP1
MOV NUM,DH
MOV NUM+1,DL
MOV AH,COUNT
SUB AH,DH
SUB AH,DL
MOV NUM+2,AH
MOV AX,4C00H
INT 21H
CODE ENDS
END START
4 . 循环结构程序示例:
在一串给定个数的数据中寻找最大值,存放到MAX存储单元中。
DATA SEGMENT
BUF DW 1234H,3200H,4832H,5600H
COUNT EQU ($-BUF)/2
MAD DW ?
DATA ENDS
STACK SEGMENT 'STACK'
STAPN DB 100 DUP(?)
TOP EQU LENGTH STAPN
STACK ENDS
CODE SEGMENT
MAIN PROC FAR
ASSUME CS:CODE,SS:STACK,DS:DATA
START:MOV AX,STACK
MOV SS,AX
MOV SP,TOP
PUSH DS
SUB AX,AX
PUSH AX
MOV AX,DATA
MOV DS,AX
MOV CX,COUNT
LEA BX,BUF
MOV AX,[BX]
DEC CX
AGAIN:INC BX
INC BX
CMP AX,[BX]
JGE NEXT
MOV AX,[BX]
NEXT:LOOP AGAIN
MOV MAX,AX
RET
MAIN ENDP
CODE ENDS
END MAIN
5 . 循环程序2:
求A和B两个4节BCD数之和,它们在内存中以压缩BCD码的形式存放,低字节在前,高字节在后。要求结果以同样形式存放在以SUM开始的单元中。
BCD码:用四个二进制位表示一个十进制数字;最常用的是8421 BCD码;
压缩型BCD码:一个字节可存放一个两位十进制数,其中高四位存放十位数字,低四位存放个位数字。如:56的压缩型8421 BCD码是0101 0110;
非压缩型BCD码:一个字节可存放一个一位十进制数,其中高字节为0,低字节的低四位存放个位。如:5的非压缩型BCD码是0000 0101,必须存放在一个字节中,56的非压缩型BCD码是00000101 00000110,必须存放在一个字中。
DATA SEGMENT
A DB 44H,33H,22H,11H
B DB 88H,77H,66H,55H
SUM DB 5DUP(0)
DATA ENDS
STACK SEGMENT 'STACK'
STAPN DB 100DUP(?)
TOP EQU 100
STACK ENDS
CODE SEGMENT
MAIN PROC FAR
ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK
START:MOV AX,STACK
MOV SS,AX
MOV SP,TOP
PUSH DS
SUB AX,AX
PUSH AX
MOV AX,DATA
MOV DS,AX
MOV ES,AX
MOV SI,OFFSET A
MOV BX,OFFSET B
MOV DI,OFFSET SUM
MOV CX,LENGTH SUM
DEC CX
CLD
CLC
MOV AH,0
GET_SUM:LODS A
ADC AL,[BX]
DAA
INC BX
STOS SUM
LOOP GET_SUM
ADC AH,0
MOV AL,AH
STOSB
RET
MAIN ENDP
CODE ENDS
END MAIN
- 例4.40 冒泡法给5个数排序
DATA SEGMENT
LIST DW 12,7,19,8,24
COUNT EQU ($- LIST)/2
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
BEGIN:
MOV AX,DATA
MOV DS,AX
MOV CX, COUNT-1
LOOP1:
MOV DX,CX
MOV BX,0
LOOP2:
MOV AX,LIST[BX]
CMP AX,LIST[BX+2]
JAE NO_CHANGE
XCHG AX,LIST[BX+2]
MOV LIST[BX],AX
NO_CHANGE:
ADD BX,2
LOOP LOOP2
MOV CX,DX
LOOP LOOP1
MOV AX,4C00H
INT 21H
CODE ENDS
END BEGIN