版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第三章汇编语言程序设计本章学习要点:通过本章学习应掌握汇编语言的编程方法和程序结构,培养模块化程序设计思想。逐步熟练掌握指令、伪指令在程序设计中的使用方法和程序的调试方法。本章主要学习内容有:
1、掌握汇编语言程序结构(分支、循环和子程序)
2、子程序参数的传递方法
3、DOS功能调用
5.1基本知识一、流程图绘制方法流程图是程序设计的基础,它是程序算法的图形描述,以图形的方式把解决问题的先后次序及程序的逻辑结构直观地、形象地描述出来。使解题思路表达清晰,便于理解和编制程序。为一个复杂任务绘制流程图时,首先要将任务分解,化为一个个小的任务模块,然后再对每个小模块再进行分解,直至每个小模块表述的都很清晰为止。故流程图的绘制也可以分为几级来画,从概括到具体,由粗到细,逐步求精。流程图一般由执行框、判别框、起止框和流向线四部分组成,如图所示。
执行框:用于说明某一段程序或某一模块的功能。通常有一个入口和一个出口。判别框:表示程序分支的流向判断,框内写判别条件。这种框通常有一个入口,多个出口,每个出口要注明分支流向条件。起止框:表示一个程序或一个程序模块的开始和结束。起始框内通常标注程序名、标号或“开始”,它仅有一个出口。终止框内通常标注“结束”、“返回”等,它仅有一个入口。起止框:表示一个程序或一个程序模块的开始和结束。起始框内通常标注程序名、标号或“开始”,它仅有一个出口。终止框内通常标注“结束”、“返回”等,它仅有一个入口。
例:在内存BUF字节数据缓冲区中存放着若干无符号数,编写一个程序,从数据区中找出最大值,并保存到AL寄存器中。分析:若是人工查找最大值,则要从第一个数据开始向后查看,将看到的第一个数据作为初始最大值,再同下一个数据进行比较,将比较后得到的最大值记住,然后再用这个最大值同下一个数据进行比较,如此下去直至全部数据比较完毕为止,那么最大值也就在大脑中产生了。从上面的分析,可以找出用计算机解决这一问题的算法。将寄存器BX作为数据指针,让它指向数据缓冲区,并把第一个数据作为初始最大值从内存中取出送AL寄存器保存。调整BX,使其再指向第二个数据,将该数据同初始最大值进行比较,如果这个数据比初始最大值大,就把该数据作为新的最大值保存到AL寄存器中,否则放弃该数据,再继续与下一个数据进行比较,这样直至比较完全部数据后,在AL寄存器中中保存的就是数据的最大值。程序框图如下:
1 DATA SEGMENT ;定义数据段
2 BUF DB85,90,78,97,…
;数据区
3 COUNT EQU$-BUF ;计算数据个数
4 DATA ENDS5 STACK SEGMENTPARASTACK ;定义堆栈段
6 DW100DUP(?) ;定义100个字的堆栈空间
7 STACK ENDS8 CODE SEGMENT ;定义代码段
9 MAIN PROCFAR ;主程序开始
10 ASSUME CS:CODE,DS:DATA,SS:STACK;分配段寄存器
11 PUSH DS ;保护返回地址
12 MOV AX,013 PUSH AX14 MOV AX,DATA ;装填数据段寄存器
15 MOV DS,AX
16 LEA BX,BUF ;数据指针BX指向数据区首地址
17 MOV AL,[BX] ;取初始值作初始最高分
18MOV CX,COUNT-1 ;设置计数器初值
19LP:INCBX ;修改数据指针,BX指向下一数据
20 CMP AL,[BX] ;数据区中的分数同“最大值”比较
21 JAE NEXT ;最大值比下一个数据大或相等时转移
22 MOV AL,[BX] ;新的“最大值”送AL保存
23NEXT:LOOP LP ;计数器(CX)>0时,转移到LP
24RET ;返回DOS25MAINENDP ;过程结束
26CODEENDS ;代码段结束
27 END MAIN
;源程序结束
程序中第11~13语句的作用是保证用户程序结束后能够正确返回DOS。用户的可执行程序(
EXE)装入内存后,用户程序的目标代码一定是直接加载在程序段前缀(ProgramSegmentPrefix,简称PSP)的后面。PSP的长度为100H字节,它给出了用户可执行文件的若干控制信息,在PSP的开始处(第1、2字节)有一条中断指令“INT20H”的代码。这条指令具有结束用户程序,返回操作系统的功能。通过该指令返回DOS是用户程序常用的一种方法。用户程序结束后如何返回这里呢?首先把用户程序设置成一个过程,其类型为FAR。由于可执行文件装入内存后,DS和ES两个段寄存器都指向PSP,所以用第11语句“PUSHDS”指令把DS内容压入堆栈,接着用第12、13语句把偏移量00H压入堆栈。这样执行第24语句RET返回指令后,DOS就会把原先压入堆栈的DS值和偏移量00H弹出,分别送入CS和IP,使程序转到PSP开始处去执行“INT20H”指令。
结束用户程序也可以使用中断指令“INT21H”返回操作系统。此时,用户程序不再设置为过程,只要在程序结束时用以下两条指令即可。
MOV AH,4CH INT 21H程序的代码段可以改写为:
CODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACK
START:MOVAX,DATA
MOVDS,AX┇
;省略部分同前一程序
NEXT:LOOPLP MOVAH,4CH ;功能号4CH送AH INT 21H ;调用DOS的21H号中断
CODEENDS ENDSTART
在程序设计时,易采用“自上而下、逐步求精”的实施方法,此方法又称为系统化程序设计方法。首先把一个大型程序分解成几个主要的模块。最高层次部分说明这些模块之间的关系以及它们的功能,也就是说,最高层次部分是对整个程序的概述。而每个主要的模块再分解成几个较小的模块,然后继续分解成更小的模块,直到每个模块内的操作步骤都很清楚、容易理解为止。可以由最小的模块开始编写程序,经测试通过后再一直往上做,直到最终完成。5.2程序设计的基本方法
5.2.1顺序程序设计顺序结构是最简单的一种程序结构形式。从开始到结束,完全按照语句顺序逐条执行的指令序列,它没有分支、循环和转移。从程序流程图看,顺序结构的程序只有一个起始框、终止框和若干个执行框,没有判别框。采用顺序结构的程序一般都是简单程序。由于程序设计比较简单,一般可不必画出流程图,直接写出源程序,下面举例加以说明。
【例3-1】求两个无符号数的平均值。这两个数分别放在X单元和Y单元中,而平均值放在Z单元中,在此设X=6、Y=8。源程序编制如下:
DATA SEGMENT XDB 6 YDB8 ZDB? DATA ENDS STACKSEGMENTPARASTACK DW 100DUP(?) STACKENDS CODE SEGMENT MAINPROCFAR ASSUMECS:CODE,DS:DATA,SS:STACK
PUSH DS MOV AX,0 PUSH AX MOV AX,DATA MOV DS,AX MOV AL,X ;AL
X ADD AL,Y ;AL
(X+Y)
MOVAH,0 ;AL扩展为字
MOV BL,2 ;BL
除数2 DIV BL ;(AX)÷2,AL
商,AH
余数
MOV Z,AL ;Z
商
RETMAIN ENDPCODE ENDS END MAIN
【例3-2】在内存中自TAB开始的16个单元连续存放着0至15的平方值(称为平方表)。任给一个数x(0
x
15),求x的平方值,并把结果放入y单元中。(P143,注:本程序优于课本)分析一下表的存放规律可知,表地址与数x的和正是x2值所在存储单元的地址。设X=12,程序如下:
DATASEGMENTTABDB0,1,4,9,16,25,36,49,64,81,100,121,144,169,196,225X EQU 12D
;书上是“?”
YDB ?DATAENDSSTACKSEGMENTPARASTACKDW100DUP(?)STACKENDSCODESEGMENTASSUME CS:CODE,DS:DATA,SS:STACK
START: MOV AX,DATA MOV DS,AX MOV BX,X MOV AL,TAB[BX] ;把表中的X2值送AL MOV Y,AL ;X2值送Y单元
MOV AH,4CH INT 21H CODE ENDS END START
5.2.2分支程序设计许多实际问题都需要根据不同的情况进行不同的处理。反映到计算机程序中就是根据不同的条件,跳到不同的程序段去执行相应的程序,这样的程序就称为分支程序。也正因为如此,计算机才有了分析和判断的能力。在汇编语言程序设计中,可以用条件转移指令实现分支结构。
1.利用比较转移指令实现分支两路分支只要用条件转移指令就能实现,对多路分支则要采用多次判断转移的方法实现,每次判断转移形成两路分支,n次判断转移可以形成n+1路分支。(P145)
1 x>0
【例3-3】求解符号函数Y=
0 x=0(-128
x
127)
-1 x<0
这是一个简单的分支结构,任意给定x值,在此设x=-2,存放在x单元,函数值y存放在y单元,根据x的值确定y的值。程序流程图如图所示。
编写程序如下:(书上例题有错) DATASEGMENTX DB −2
;书上是“X” Y DB ? DATAENDS STACK SEGMENTPARASTACK DW100DUP(?) STACK ENDS CODESEGMENTASSUMECS:CODE,DS:DATA,SS:STACK MAINPROCFAR PUSH DS MOV AX,0 PUSH AX MOV AX,DATA MOV DS,AX
MOV AL,X ;AL
X CMP AL,0 JGE BIG ;X0时跳转
MOV AL,-1 ;X<0时,Y-1 JMPS1 BIG: JEEQZ ;X=0时跳转
MOVAL,1 ;X>0时,Y1 JMPS1 EQZ: MOVAL,0 ;X=0时,Y0 S1: MOVY,AL RETMAIN ENDPCODE ENDS ENDMAIN课后请将本例与书上例题比较,掌握这两种程序结构的使用方法。
┇ CMP AL,00H JZSBR0 CMP AL,01H JZSBR1 ┇ CMP AL,07H JZ SBR7 ┇5.2.3循环程序设计
循环结构是重复执行某一段程序的一种结构形式。凡是需重复执行的程序段都可以按循环结构设计。
一、单循环程序设计
1、循环程序的两种结构形式
【例3-5】在内存BUF单元中存放着若干字节型带符号数,编写程序统计其中负数的个数,统计结果放在REST单元。(P150,例1)
DATA SEGMENT BUFDB-1,23,-4,67,…
CONTEQU$-BUF RESTDW? DATA ENDS CODESEGMENT MAIN PROCFAR ASSUMECS:CODE,DS:DATA PUSH DS MOV AX,0 PUSH AX MOV AX,DATA MOV DS,AX
MOVBX,OFFSETBUF MOVCX,CONT ;数据个数送CX MOVDX,0 ;DXLP1:MOVAL,[BX] ;取数据送AL ANDAL,AL ;影响标志位
JNSPP ;正数不统计,跳转
INCDX ;是负数DX加1PP: INCBX ;修改数据指针
LOOPLP1 ;判断下一数据正负
MOVREST,DX ;存结果
RETMAIN ENDPCODE ENDSENDMAIN
【例3-5】在内存Y单元中存放着数n,编写程序把数n中“1”的个数统计出来放在COUNT单元。(P150,例2)一种方法是对数n逐步按位测试来统计“1”的个数,以数n的位长作为循环结束条件。这种方法对n=0的情况也要从头至尾逐位判断,能否把n=0的情况立刻判断出来缩短程序执行时间呢?这就要采用“先判断后执行”循环结构,首先测试n是否为0来作为循环结束条件,节省程序执行时间。这是一种按条件控制循环结束的方法。程序框图及源程序如下:
DATA SEGMENT YDW n ;调试程序时“n”应写成具体数值
COUNTDW ? DATA ENDS CODESEGMENT MAIN PROCFAR ASSUMECS:CODE,DS:DATA PUSH DS MOV AX,0 PUSH AX MOV AX,DATA MOV DS,AX MOV CX,0 ;初始化CX,用于计数
MOV AX,Y ;数n送AX
RP: ANDAX,AX;测试AX内容,也可用TESTAX,0FFFFH JZEXI ;(AX)=0转移
SHIF: SHLAX,1 ;AX内容逻辑左移一位
JNCZR ;CF中是0转移
INCCX ;CF中是1,CX内容加1ZR: JMPRP ;返回继续检测
EXI: MOVCOUNT,CX ;把n中1的个数送COUNT单元
RETMAIN ENDPCODE ENDSENDMAIN
【例3-6】设计一个程序使它能够把BX寄存器内的二进制数用十六进制数的形式在屏幕上显示出来。根据题意应该把BX中的二进制数每四位划分为一组,从左到右依次把每组的十六进制值在屏幕上显示出来,显然这个问题可以使用循环结构完成,每次循环显示一位十六进制数,由于BX字长16位,每次处理4位,共需循环处理4次,这样循环次数是已知的,可以使用循环计数的方法控制循环。在循环体内先将二进制数分组,然后再将其转换为可显示的ASCII码,通过DOS系统功能调用将字符从显示器上显示出来(关于DOS系统功能调用将在以后讲述)。字符0~9的ASCII码为30H~39H,而字母A~F的ASCII码为41H~46H,所以将4位二进制数转换为ASCII码的方法是,值为0~9的4位二进制数只要加上30H后即为ASCII码,而对于值为10~15的4位二进制数还要再加上7才能显示出字符A~F,因为从3AH~40H一共有7个字符需要跳过去。程序框图及程序如下:
CODE SEGMENTMAIN PROCFARASSUMECS:CODE PUSH DS MOV AX,0 PUSH AX MOV BX,10101011111101B ;二进制数送BX MOV CH,4 ;共需转换4组ROT: MOV CL,4 ;每组四位
ROL BX,CL ;左循环移位
MOV AL,BL ;AL
BL AND AL,0FH
;清AL中高4位
CMPAL,9 JBEDSP ADD AL,7 ;为转换成A~F做准备
DISP: ADDAL,30H ;转换成ASCII码
MOV DL,AL ;ASCII码送DL MOV AH,2 ;功能号送AH INT 21H ;显示字符
DEC CH ;每完成一组转换,CH值减1 JNZ ROT ;4组二进制数没有转换完转移
MOV DL,‘H’ ;显示字符“H”表明是十六进制
MOV AH,2 INT 21H RETMAIN ENDPCODEENDS ENDMAIN
二、多重循环程序设计多重循环又称循环嵌套,即循环套循环。多重循环程序设计的基本方法和单重循环程序设计是一致的。在使用多重循环时,内循环必须完整的包含在外循环之中,循环可以嵌套、并列,但不能交叉。可以从内循环中直接跳到外循环,但不能从外循环中直接跳进内循环。无论是外循环,还是内循环,决不能使循环返回到初始化部分,否则会出现“死循环”,这一点要特别注意。
【例3-7】从键盘读入一位3~9之间的数字,输出一个用“
”组成的三角形,例如读入3,输出
本题可以用双重循环进行设计,内层循环用CX计数,控制一行输出“
”的个数,外层循环也用CX计数,用来控制行数。在内层循环开始时,首先把外层循环的CX压入堆栈,当内层循环结束后再立即恢复外层循环CX的计数值。(关于DOS功能调用在后面章节讲解)
DATA SEGMENTMESS DB‘Pleaseinputanumber:$’DATA ENDSCODE SEGMENTASSUMEDS:DATA,CS:CODEBEGIN:MOV AX,DATA MOVDS,AX LEA DX,MESS MOVAH,09H ;DOS功能调用,显示字符串
INT21HKEYIN:MOVAH,1 INT21H ;从键盘取数
CMP AL,33H ;同“3”比较
JBKEYIN ;小于“3”重新输入
CMPAL,39H ;同“9”比较
JAKEYIN ;大于“9”重新输入
AND AL,0FH ;把ASCII码转换为二进制数
CBW ;把AL中字节数据扩展成字
MOV CX,AX ;该数作为外层循环数送CX MOV AH,2 ;DOS中断的2号功能调用
MOV DL,0DH ;0DH是“回车”的ASCII码
INT 21H ;使光标回到所在行的行首
MOV DL,0AH ;0AH是“换行”的ASCII码
INT 21H ;使光标换行
L2:PUSH CX ;外层循环计数值入栈保存
L1:MOV DL,‘
’ MOV AH,2 INT 21H ;在一行上循环打印“
”
LOOP L1
MOV DL,0DH INT 21H ;光标回到行首
MOV DL,0AH INT 21H ;光标下移一行
POP CX ;外层循环计数值出栈
LOOP L2 ;在新行上循环打印“
”
MOV AH,4CH INT 21HCODE ENDS END BEGIN
练习1:在字节型数据区da1中有若干个字符,编写一个程序统计大写字母B出现的次数,结果送sum。(思考:查找替换问题)
datasegmentda1db‘eFDhi
abcd
ABCD'numequ$-da1sumdb0dataendscodesegmentmainprocfarassumecs:code,ds:datapushds
movax,0pushax
mov
ax,data
mov
ds,ax
mov
cx,numleasi,da1nt:cmpbyteptr[si],‘B'
jne
aaincsumaa:incsiloopntretmainendpcodeendsendmain
datasegment
bufdb‘eFDhi
abcd
ABCD'numequ$-bufdataendscodesegmentmainprocfarassumecs:code,ds:datapushds
movax,0pushax
mov
ax,data
mov
ds,ax
mov
cx,numleasi,buf
nt:cmp
byteptr[si],'A'
jb
aa
cmp
byteptr
[si],'Z'
ja
aa
mov
bl,[si]addbl,20h
mov[si],blaa:incsiloopntretmainendpcodeendsendmain练习2:在字节型数据区buf
中有若干个字符,编写一个程序将其中的大写字母转换为小写字母。(思考:小写转大写)
练习3:在字节型数据区buf
中存放着若干个有符号数,编写一个程序将其中的最大数和最小数分别存放到n_max和n_min字节单元。
datasegment
bufdb-2,5,8,-9,16h,-0ahnumequ$-da1
n_maxdb?
n_mindb?dataendscodesegmentmainprocfarassumecs:code,ds:datapushds
movax,0pushax
mov
ax,data
mov
ds,ax
leasi,buf
mov
al,[si]
mov
n_max,al
mov
n_min,alincsi
movcx,num-1nt:mov
al,[si]
cmp
n_max,al
jgea1
mov
n_max,ala1:cmp
n_min,al
jlea2
mov
n_min,ala2:incsiloopntretmainendpcodeendsendmain
作业:在字节型数据区buf
中存放着若干个有符号数,编写一个程序将统计其中的正数和负数的个数,统计结果分别存放到p_num和n_num字节单元。
5.2.4子程序设计一、基本概念子程序又称为过程,相当于高级语言中的过程和函数。在一个程序的不同部分,如果多次出现一些类同的程序段,它们在功能上和结构形式上都相同,只是变量的赋值不同,此时就可以把这样的程序段写成子程序形式,以便需要时调用它。调用子程序的程序称为主程序或调用程序。子程序结构是实现模块化程序设计的重要工具和手段。为什么要使用子程序?在前面用“
”号构成三角形图案的【例3-6】题中,有两处使用了回车和换行功能的程序段,因此可以使用子程序使其简化。
【例3-6】程序回顾:
DATA SEGMENTMESS DB‘Pleaseinputanumber:$’DATA ENDSCODE SEGMENTASSUMEDS:DATA,CS:CODEBEGIN:MOV AX,DATA MOVDS,AX LEA DX,MESS MOVAH,09H ;DOS功能调用,显示字符串
INT21HKEYIN:MOVAH,1 INT21H ;从键盘取数
CMP AL,33H ;同“3”比较
JBKEYIN ;小于“3”重新输入
CMPAL,39H ;同“9”比较
JAKEYIN ;大于“9”重新输入
AND AL,0FH ;把ASCII码转换为二进制数
CBW ;把AL中字节数据扩展成字
MOV CX,AX ;该数作为外层循环数送CX
MOV AH,2 ;DOS中断的2号功能调用
MOV DL,0DH ;0DH是“回车”的ASCII码
INT 21H ;使光标回到所在行的行首
MOV DL,0AH ;0AH是“换行”的ASCII码
INT 21H ;使光标换行
L2:PUSH CX ;外层循环计数值入栈保存
L1:MOV DL,‘
’ MOV AH,2 INT 21H ;在一行上循环打印“
”
LOOP L1
MOVAH,02H
MOV DL,0DH INT 21H ;光标回到行首
MOV DL,0AH INT 21H ;光标下移一行
POP CX ;外层循环计数值出栈
LOOP L2 ;在新行上循环打印“
”
MOV AH,4CH INT 21HCODE ENDS END BEGIN
┇ ;省略部分与例题4-9相同
AND AL,0FH ;把ASCII码转换为二进制数
CBW MOV CX,AX ;该数作为外层循环数送CX
CALL CRLF
;调用CRLF子程序
L2:PUSH CX ;外层循环计数值入栈保存
L1:MOV DL,‘
’ MOV AH,2 INT 21H LOOP L1 ;在一行上循环打印“
”
CALL CRLF
;调用CRLF子程序
POP CX ;外层循环计数值出栈
LOOP L2 ;在新行上循环打印“
”
MOV AH,4CH INT 21H;采用子程序结构
;----以下是完成回车换行功能的子程序----CRLF PROC NEAR
MOV AH,2 ;DOS功能调用号送AH MOV DL,0DH ;0DH是“回车”的ASCII码
INT 21H ;使光标回到所在行的行首
MOV DL,0AH ;0AH是“换行”的ASCII码
INT 21H ;使光标换行
RET
CRLF ENDPCODE ENDS END BEGIN
二、子程序定义及其属性子程序是用过程定义伪指令PROC和ENDP来定义的,其过程类型属性的确定原则如下:调用程序和过程在同一代码段中则使用NEAR属性;调用程序和过程不在同一代码段中则使用FAR属性;主程序应定义为FAR属性,因为程序的主过程看成是DOS调用的一个子程序,而DOS对主过程的调用和返回都是FAR属性。此外,过程定义允许嵌套,即在一个过程定义中允许包含多个过程定义。
1、调用程序和子程序同在一个代码段中,程序格式如下:
CODESEGMENT┇
MAINPROCFAR;主程序
┇CALLPGM1;子程序调用语句
┇ RETPGM1PROCNEAR;被调用的子程序
┇
RETPGM1 ENDP
MAIN ENDPCODE ENDS
2、当调用程序和子程序不在同一代码段时,其程序格式如下:
CODE1SEGMENT┇
SUB_PGMPROCFAR
;被调用的子程序
┇ RET SUB_PGMENDP┇
CODE1 ENDS
CODE2 SEGMENT ┇ CALL SUB_PGM
;子程序调用语句
┇
CODE2 ENDS
三、寄存器的保护与恢复在程序设计中调用程序与子程序通常是独立编写的,因此它们所使用的一些寄存器经常会发生冲突。如果调用子程序之前的某些寄存器内容在子程序返回主程序后还要使用,而子程序又恰好使用了这些寄存器,那么这些寄存器的原有内容就会遭到破坏,从而使程序运行出错。为防止这种错误的发生,就必须对相关寄存器内容进行保护,其处理方法有以下两种。1.在主程序中实施保护
┇ PUSH BX ;保存BX内容
PUSH CX ;保存CX内容
CALL SUB1 ;调用子程序
POP CX ;恢复CX内容
POP BX ;恢复BX内容
┇
2.在子程序中进行保护
SUB1 PROC NEAR PUSH BX ;保存寄存器内容
PUSH CX ┇ ;子程序功能指令序列
POP CX ;恢复寄存器内容
POP BX RETSUB1 ENDP
5.2.5DOS系统功能调用一、概述在汇编语言程序设计中,经常要用到BIOS(BasicInput/OutputSystem)的一些软中断和DOS系统功能调用来扩充汇编语言的功能。系统功能调用是DOS为用户提供的一组常用子程序,这些子程序大致分为设备管理、文件管理和目录管理等几类。这里主要介绍部分DOS系统功能调用,通过这些例子掌握其使用方法,关于BIOS中断和其它DOS功能调用,可参阅其它参考书自学。二、DOS功能调用的使用方法
DOS功能调用是由中断指令“INT21H”实现的,具体调用该中断的哪一个功能由其功能号来指定。程序设计人员可不必了解中断子程序的内部结构和细节,只需按以下三步完成DOS功能的直接调用。
(1)入口参数送指定寄存器(2)功能号送AH
(3)INT21H发出中断请求指令下面以数据的输入/输出功能为例,说明DOS功能调用的方法。
1.带显示键盘输入(功能号01H)
调用格式: MOVAH,01H INT21H功能:计算机等待键盘输入一个字符,若有字符输入,则首先检查是否为Ctrl+Break或Ctrl+C键,若是,则退出本次调用,否则将键值送入AL寄存器,同时把这个字符送屏幕显示。入口:无出口:AL中存放键盘输入的字符(ASCII码)。
2.显示字符(功能号02H)
调用格式: MOV DL,‘字符’(或字符的ASCII码)
MOV AH,02H INT 21H
功能:显示DL寄存器中的字符,在字符输出时若是Ctrl+Break或
Ctrl+C,则退出本次调用。入口:DL寄存器存放要显示字符的ASCII码值。出口:无3.打印字符(功能号05H)调用格式: MOV DL,’字符’(或字符的ASCII码)
MOV AH,05H INT 21H
功能:打印DL寄存器中的字符,在字符输出时若有Ctrl+Break或
Ctrl+C,则退出本次调用。入口:DL寄存器存放要打印的ASCII码值。出口:无
4.直接控制台输入输出(功能号06H)
调用格式: MOV DL,X MOV AH,06H INT 21H功能:从标准输入设备(如:键盘)输入字符,也可以向屏幕输出字符,但不检查Ctrl+Break或Ctrl+C。(1)输入方式当X=FFH时,表示从键盘输入,若标志ZF=0,表示AL中为键入的字符值;若标志ZF=1,表示AL中不是键入的字符值,即无键按下。例如:
MOV DL,0FFH MOV AH,06H INT 21H
【例5-17】用DOS功能的6号调用循环检查键盘,若有字符输入则显示输入的字符,若遇到回车(0DH)则退出程序。
CODESEGMENT ASSUMECS:CODESTART:MOV DL,0FFH ;置字符输入方式
MOV AH,06H ;6号功能调用
INT 21H ;
键盘检查,读输入字符
JZSTART ;没有字符输入,再次检查键盘
CMP AL,0DH ;输入的是回车符吗?
JZQQ ;是,退出程序(2)输出方式当X
FFH时,表示向屏幕输出,DL中为输出字符的ASCII码值。
例如: MOV DL,41H;向屏幕输出字符“A” MOV AH,06H INT 21H
MOV DL,AL ;不是,显示输入字符
MOV AH,06H INT 21HJMP START ;继续查看键盘
QQ: MOV AH,4CH INT 21HCODE ENDS END START5.无显示字符输入(功能号07H)调用格式: MOV AH,07H INT 21H功能:计算机等待键盘输入一个字符,并将键值送入AL寄存器,但不把这个字符送屏幕显示,也不检查Ctrl+Break或Ctrl+C键。入口:无出口:AL是键盘输入的字符(ASCII码)。
6.无显示字符输入(功能号08H)
调用格式: MOV AH,08H INT 21H功能:计算机等待键盘输入一个字符,若有字符输入,则首先检查是否为Ctrl+Break或Ctrl+C键,若是,则退出本次调用,否则键值送入AL寄存器,但输入的字符不在屏幕上显示。入口:无出口:AL中是存放键盘输入的字符(ASCII码)。7.字符串显示(功能号09H)调用格式: MOV AH,09H INT 21H功能:在屏幕上输出内存中以$符作为结束标志的字符串,但不显示$结束符。非显示字符(如回车、换行)可以用它的ASCII码插入字符串中间。入口:DS:DX指向字符串首地址出口:无
示例:
DATA SEGMENT BUF DB‘HOWDOYOUDO?$’ ;要显示的字符串
┇ DATA ENDS CODE SEGMENT┇ MOV AX,DATA ;把数据段地址
MOVDS,AX ;送DS┇ LEA DX,BUF ;BUF偏移地址送DX MOV AH,09H ;9号功能调用
INT 21H┇ CODE ENDS
8.字符串输入(功能号0AH)
调用格式: MOV AH,0AH INT 21H
功能:从键盘输入字符串到内存输入缓冲区,以回车键作为结束。入口:DS:DX指向内存缓冲区,缓冲区第一个字节是用户设置的最大输入字符数(1~225),含回车键码。出口:缓冲区第二个字节存放用户本次调用时实际输入的字符数(不包括回车符),这个数由DOS返回时自动填入。从键盘上接收的字符从第三个字节开始存放,直到用户输入回车键为止,并将回车键码(0DH)加在输入字符串的末尾。所以设置缓冲区最大长度时,要比希望输入的最多字符数多一个字节。若实际输入的字符数超过缓冲区最大容量,后面输入的字符被略去,且响铃提示,直到输入一个回车键才结束。
示例:最多输入50个字节。
DATA SEGMENT
BUFDB51
;串长度为51个字节,含回车码
DB?
;存放实际输入的字符个数
DB51DUP(?)
;定义51个字节,含回车码
┇ DATA ENDS CODE SEGMENT ┇ MOV AX,DATA MOV DS,AX ┇
MOV DX,OFFSETBUF
;DS:DX指向数据缓冲区BUF
MOV AH,0AH
;调用功能号送AH
INT 21H ┇ CODE ENDS
9.获取中断向量(功能号35H,P318)
调用格式: MOV AL,中断类型号
MOV AH,35H INT 21H
功能:按指定的中断类型号从中断向量表中取出中断向量。入口:AL寄存器存放待获取中断向量的中断类型号。出口:中断向量的段值和偏移量分别放在ES和BX中。10.设置中断向量(功能号25H,P315)调用格式:MOVAL,中断类型号;(新中断向量放在DS:DX中)
MOVAH,25HINT21H
功能:将指定的中断类型号在中断向量表中的中断向量设置成新指定的中断向量。入口:AL存放中断类型号,新中断向量的段值和偏移量分别放在DS
和DX中。出口:无
下面进一步举例说明DOS功能调的使用方法。【例】利用DOS功能调用实现人机对话。在屏幕输出“Whoareyou?”然后把键盘输入的信息送内存数据缓冲区NAME中,并显示输入信息。(与P179的例7.1类似)
DATA SEGMENT NAM DB10,?,10DUP(?)
ASK DB‘Whoareyou?’,‘$’ DATA ENDS CODE SEGMENT ASSUMECS:CODE,DS:DATA START:MOV AX,DATA MOV DS,AX
MOV DX,OFFSETASK
;输出字串首址送DX
MOV AH,09H
;9号功能调用
INT 21H
;输出字串
MOV DX,OFFSETNAM ;输入字串首址送DX MOV AH,0AH ;10号功能调用
INT 21H ;读入以回车结束的字串
MOV SI,OFFSETNAM ;SI指向NAM单元
XOR AX,AX ;清AX MOV AL,[SI+1] ;输入的字符数送AL ADD SI,AX ;使SI指向倒数第2个字符
MOV BYTEPTR[SI+2],’$’;在最后一个字符后添加$字符
MOV DL,0AH ;换行
MOV AH,02H INT 21H MOV DL,0DH ;回车
MOV AH,02H INT 21H MOV DX,OFFSETNAM+2;DX指向输入内容
MOV AH,09H INT 21H ;将读入字串再输出
MOV AH,4CH INT 21HCODE ENDS END START【例】将C盘USR子目录中的MY.ASM文件变为隐含属性文件。
DATA SEGMENT F_NAMEDB‘C:\USR\MY.ASM’,0;ASCIZ串
DATA ENDS CODE SEGMENT ASSUMECS:CODE,DS:DATA BEGIN:MOV AX,DATA MOV DS,AX
MOV AH,43H ;43H号功能调用
MOV AL,01H ;1置(0取)文件属性
MOVCX,02H ;02H为隐含属性(注)
LEA DX,F_NAME;文件名首址送DX INT 21H ;修改文件属性
MOV AH,4CH INT 21HCODEENDS END BEGIN
注:CX中第0位为1表示文件是只读属性,第1位为1表示隐含属性,第2位为1表示系统文件,第3位为1表示卷标,第4位为1表示子目录,第5位为1表示归档文件,第6至7位未用。(参见P320)END
【实验,自学】
编制一个程序,将十进制数转换为十六进制数,要求从键盘取得一个十进制数,然后把该数以十六进制形式在屏幕上显示出来,再读数,再显示,如此循环,直到键入Ctrl+C为止。根据题意,用一个KEY_ASTOB子程序完成键盘输入和十进制数到二进制数的转换;用SPACE_2子程序完成空格;用BTOH_DISP子程序完成二进制到十六进制显示;再用一个CR_LF子程序完成回车和换行。主程序和子程序之间参数传递使用寄存器BX。
KEY_ASTOB子程序说明:十进制数有若干位,而每输入1位十进制数数,原来已输入的每一位数字都要向高位移一位,也就是扩大10倍,然后再把新输入的数字加到个位上。在KEY_ASTOB子程序中采用的方法与它类似,每输入一位数(ASCII码)都要先把它转换为二进制数,每得到这样一个新的二进制数,原来已得到的二进制数就要乘10,然后再加上这个新的二进制数,这样得到的二进制数才能与已输入的十进制数相当。通过分析本题程序编制如下:
DATA SEGMENTMESS1 DB‘Pleaseinputanumber:$’MESS2 DB07H,07H,08H,’$’ ;响铃、退格
DATA ENDS CODESEGMENT ASSUME
CS:CODE,DS:DATA
;----
以下是主程序部分----
MAIN PROCFAR PUSH DS MOV AX,0 PUSH AX MOV AX,DATA MOV DS,AXRP: CALL KEY_ASTOB CALL CR_LF CALL BTOH_DISP CALL CR_LF JMP RP MAIN ENDP
;----以下是KEY_ASTOB子程序----
KEY_ASTOBPROCNEAR LEA DX,MESS1 ;显示提示信息
MOV AH,09H INT 21H MOV BX,0 ;BX存放输入的数据
NEWCH: MOV AH,1 ;从键盘取一位数
INT 21H CMP AL,0DH JZ EXIT AND AL,0FH ;把ASCII码变为二进制数
JL ER ;若小于0(非数字)跳转
CMP AL,9D ;同9比较
JG ER ;大于9(非数字)跳转
MOV AH,0 ;为了把AL中的字节内容扩展为字
XCHG AX,BX;交换数据后,新数在BX,原数在AX MOV CX,10D;十进制数10送CX MUL CX ;AX中的原数乘10,结果送AX XCHGAX,BX;乘10后的结果在BX,新数在AX ADD BX,AX;乘10后的原数和新数相加,结果送BX JMP NEWCH;跳转后等待再次输入数据
ER: MOV AH,09H;退格、响铃后,重新输入
LEA DX,MESS2 INT 21H JMP NEWCHEXIT: RET ;结束输入和转换,返回主程序KEY_ASTOBENDP
;----以下是BTOH_DISP子程序----
BTOH_DISP PROCNEAR MOV CH,4 ;外循环置数,需转换四组二进制数
ROT: MOV CL,4 ;内循环置数,每四位二进制数为一组
ROL BX,CL ;BX的内容循环左移四位
MOV AL,BL AND AL,0FH ;屏蔽掉高四位
OR AL,30H ;转换为ASCII码
CMP AL,3AH ;同ASCII码“10”比较
JL DISP ;小于10转移
ADD AL,7H ;不小于10转换成A~FDISP: MOV DL,AL MOV AH,2 INT 21H ;AL中的内容送显示
DEC CH ;外层循环数减1 JNZ ROT ;CH
0跳转
MOV DL,‘H’ ;显示字符H,表示是十六进制数
MOV AH,2 INT 21H RETBTOH_DISPENDP
;----
以下是CR_LF子程序----CR_LF PROC NEAR MOV DL,0DH ;0DH是“回车”的ASCII码值
MOV AH,2 INT 21H MOV DL,0AH ;0AH是“换行”的ASCII码值
MOV AH,2 INT 21H RETCR_LF ENDPCODEENDSENDMAIN
以下为自学内容
MOVAH,2CHINT21H出口:
CH:CL:DH:DL=时:分:秒:1/100秒(十六进制)实时钟信息的读写操作(1)
实时钟信息的读写操作(2)
对存放在芯片RAM中的实时钟信息进行存取,需使用两个I/O端口:地址端口和数据端口,相应的端口地址分别是70H和71H。因此,对RTCMOSRAM芯片内部的64个字节内容读写操作时,要分两步进行:1.读操作(1)先把需读出的RAM单元位移地址送到地址端口(070H)。(2)再从数据端口(07lH)读出该单元的内容。例1:要求读取“星期几”的日期信息,则其读出操作的程序段如下:
MOVAL,6H;6H是存放“星期几”的单元位移地址
OUT070H,AL;送地址端口
JMPSHORT$+2
;
I/O延时
INAL,
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 【新教材】统编版(2024)八年级下册道德与法治期末必背考点提纲填空练习版(含答案)
- 河北石家庄石门实验校2026年中考试题猜想物理试卷含解析
- 广东省佛山市禅城区2026年中考一模物理试题含解析
- 2026年咸宁市通城县中考适应性考试物理试题含解析
- 2026 年中考道德与法治答题技巧考前指导讲义
- 江苏省连云港2026年中考三模物理试题含解析
- 钢结构施工方案
- 中医护理计划单
- 护理核心制度与护理工作改进
- 2026年黑龙江省齐齐哈尔市梅里斯区达呼店中学中考二模物理试题含解析
- 备战2025年高考物理大题突破大题15热力学定律的综合应用(原卷版+解析)
- 数学课程与教学论(傅海伦)
- 医疗数据合规白皮书 2025
- 幼儿美术团扇课件
- 消防队保密安全课件
- 供应商评估报告表
- 国际疾病诊断编码库ICD-11(带疾病科室分类)
- 静态网页设计(石家庄工程职业学院)知到智慧树答案
- DB51∕T 5066-2018 四川省居住建筑油烟气集中排放系统应用技术标准
- 2024年北京中考地理试卷
- (高清版)JTGT 3334-2018 公路滑坡防治设计规范
评论
0/150
提交评论