




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第4章汇编语言程序设计.ASM.OBJ.EXE编译连接编译程序:
MASM.EXE连接程序:
LINK.EXE用户编写程序,程序在计算机中运行,计算机的控制由操作系统交给用户程序,运行用户程序,当用户程序运行结束后,应再将控制权交回操作系统,所以,在程序中应该有返回DOS的指令。在计算机中,返回DOS的指令是操作系统中的一个子程序,用户使用时应调用这个子程序。系统占用INT20H
程序段前缀用户数据区用户堆栈区用户代码段…………系统和ROM占用无论用户程序有几段,也无论这些段的排列顺序如何,用户程序的代码前一定有100个字节的程序段前缀(ProgramSegmentPrefix,简称PSP),PSP给出了用户的可执行文件(.EXE)的若干控制信息。其中PSP的开始处(第1,2字节)有一条中断指令INT20H的代码,这条指令的功能是结束用户程序,返回操作系统。在用户程序执行完以后,通过执行该条指令就可以返回DOS。如何使用户程序执行完后返回来执行这条指令?系统占用INT20H
程序段前缀用户数据区用户堆栈区用户代码段……RET系统和ROM占用DS,ESSSCS首先将用户程序定义为一个远过程,当可执行文件装入内存后,DS,ES两个段寄存器被CPU自动设置为指向PSP的首址,所以一般程序的开始指令为:
PUSHDSXORAX,AXPUSHAX即将DS的内容和0000H压入堆栈,程序结束时的最后一条语句为RET,就把压入堆栈的PSP段的段基址和偏移量0000H弹出并送入CS和IP,转而执行返回DOS的指令INT20H。00H00HPSPLPSPH堆栈情况返回操作系统的另一个办法是用系统调用中断指令:INT21H,在用户程序结束时,用下面两条指令:
MOVAH,4CHINT21H这两条指令经常用在短的程序段中,即用户程序并不是一个完整的汇编程序,而只是由一些指令组成的、没有堆栈区或数据区的程序段。伪指令:伪指令不是处理器运行的指令,而是程序员给汇编程序下达的命令。是在编译源程序期间由汇编程序执行的命令。因为程序要分段放在内存内,编译程序必须要知道每段的起始位置,为CPU的段寄存器分配地址;如果程序中有变量,还要定义变量空间,存放数据、结果;知道源程序的开始、结束标志……伪指令语句:在汇编时不产生二进制代码,仅为编译程序提供汇编时所需要的信息的语句。一、段定义一般的源程序分为4个段:代码段Code、数据段Data、堆栈段Stack、附加段Extra。各个段从段定义语句开始,到段结束语句ENDS结束。段名
SEGMENT
定位类型组合类型类别……段体……段名
ENDS用户指定可任选定义段名必须是合法是标识符。定位类型:内存可以看成是一本书,将其分成页,段,字,和字节每256个地址为一页(PAGE),每页的起始地址为二进制:************0000000016进制:***00H第一页(256个地址)第二页(256个地址)00000H000FFH00100H00200H001FFH每2个地址为一个字(WORD),每个字的起始地址为偶数;最基本的类型是字节(BYTE),字节只包含一个地址,可以是内存的任何空间。定位类型表示所定义的段存放在内存空间时,段首地址对内存空间的要求,即段起始点是放在一页的起点上(PAGE)还是一段的起点上(PARA)等,如果不定义定位类型,编译程序将默认其为段类型,即将段首地址放在从****0H开始的内存空间BYTE:
表示本段起始单元可以从任一地址开始;WORD:
表示本段起始单元从一个偶地址开始;PARA:
表示本段起始单元从一个段的边界开始(默认);PAGE:
表示本段起始单元从一个页的边界开始。组合类型组合类型是告诉编译程序,所定义的段与其他段的关系,即将该段存放内存时,是否将该段与其他段在物理上或逻辑上放在一起。常常一个汇编程序可以有很多代码段、数据段或堆栈段,这时,就要综合考虑各段的组合类型。NONE:
表示本段与其他段不发生任何关系,该段有自己的基地址,是默认的组合关系。PUBLIC:在满足定位类型的前提下与其他模块的同名段连接在一起,形成一个新的逻辑段,共用一个段基址。MEMORY:
表示本段在存储器中应定位在所有其他段的最高地址。AT<表达式>:表示本段从表达式指定的地址处开始装入,这样,在程序中用户就可以直接定义段地址,这种方式不适用于代码段。类别:是用单引号括起来的字符串,连接时,LINK程序把类别相同的段放在连续的存储区中(可以不同名)。类别名可以任意,但一般为‘CODE’,’STACK’,‘DATA’等,表明该段的类型例如:定义堆栈段如下:STSEGMENTPARASTACK‘STACK’DB100DUP(?)STENDS段名组合类型类别定位类型堆栈长度段结束通过定义,自动初始化了SS和SP。………………SS:0000HSS:0063HSS:0064H100字节SP连接两个汇编语言目标程序时,它们的数据段同名,组合类型为PUBLIC,定位类型为PARA。连接后第一个目标程序的数据段的起始物理地址是01010H,长度为17AH,则第二个目标程序数据段的起始物理地址为多少?01010H+17AH=0118AH因为第二个数据段的定位类型为PARA,故应从节(段)的边界开始,01190H因为组合类型为PUBLIC,所以共用一个段基址,在内存中顺序存放。二、过程定义过程的含义和子程序是一样的,一个码段中可以包含一个或多个过程。码段名SEGMENT过程名1PROCFAR
……RET过程名1ENDP过程名2PROCNEAR
……RET过程名2ENDP…………码段名ENDSFAR:
该过程为远过程,调用该过程时为段间调用,即CS和IP均要重新赋值;NEAR:
该过程为近过程,调用该过程时为段内调用,只赋值IP。(默认)过程名1
PROCFAR……RET过程名1
ENDP过程名是合法的标识符;一个程序的主过程(起始指令所在的过程)应是FAR过程,因为该过程是DOS调用的。过程中应有RET指令,以便返回到调用处。过程可以嵌套调用,但不可以嵌套定义。过程开始过程结束例:延时100ms的子程序,编程如下:DELAY
PROC
MOVBL,10AGAIN:MOVCX,2801HWAIT:LOOPWAITDECBLJNZAGAIN
RETDELAY
ENDP系统和ROM占用用户代码段…………用户堆栈区用户数据区程序段前缀系统占用00000HDS,ES100个字节SS用户程序空间FFFFFHCS正确的DS地址MOVAX,数据段名MOVDS,AX四、结束语句ENDENDS:
段结束ENDP:过程结束END:
整个汇编源程序结束(不配对使用)汇编程序在编译时遇到END,便得知源程序已经结束。END表达式表达式为可执行程序运行的起始位置,一般为主过程名。五、ORGORG表达式指定了在其后的指令或数据存放的偏移地址。ORG0100HMOVAX,0表明该指令放在码段,其偏移地址为0100H。码段的首地址从CS:0000H处开始。PUSHDSXORAX,AXPUSHAXMOVAX,DATAMOVDS,AX标准程序前奏,一般写在代码段开始第二节数据定义一、常量、变量及标识符常量:二进制(B),八进制(Q),十六进制(H),十进制(D)(默认)10001100100B244Q64H‘AB’变量:代表存放在某些存储单元的数据,这些数据在程序的运行期间随时可以修改。在程序中以变量名的形式出现。定义变量:给变量分配存储单元,为这个单元起名字(变量名),可以同时将这些存储单元预置初值。每个变量都有三个属性段属性(SEG)
变量所在的存储单元的段基址偏移量属性(OFFSET)
变量所在的存储单元距段起点的字节数类型属性(TYPE)
一个单位变量占用存储单元的字节数,分为:
DB(1个字节)DW(2个字节)DD(4个字节)DQ(8个字节)DT(10个字节)
DATASETMENTXDB5,4YDW40HZDD2030HDATAENDS05H04H40H00H30H20H00H00HDS:0000HXYZX,Y,Z分别都有三个属性:段基址,偏移量,类型值这三个属性都有固定的值。标识符:给指令或某一存储单元地址所起的名字标识符由下列字符组成:字母:A~Z,a~z;数字:0~9;特殊字符:?.@_$数字不能作标识符的第一个字符,标识符最长为31个字符。标识符后面跟冒号时,表示标号,代表该行指令的起始地址,标号可以被转移、调用指令直接引用标识符后面不带冒号时,表示变量。标号:代码段中某一条指令的地址。标号有3个属性:段属性(SEG)
该条指令所在段的段基址偏移量属性(OFFSET)
该指令的偏移地址(距段起点的字节数)距离属性表示该标号是作为段内还是段间被调用或转移的,该属性有两个值:NEAR(FFFFH,-1):
本标号只能被标号所在段的转移或调用指令所访问(段内转移),标号后有冒号;FAR(FFFEH,-2):
本标号可被其他段(不是标号所在段)的转移或调用指令访问(段间转移)。标号名LABELFAR二、数据定义伪操作DB:定义字节,其后的每个操作数占有一个字节单元,连续存放;BUFFERDB2,3,505H03H02HBUFFERDW:定义字,其后的每个操作数占有两个字节;BUFDW2,3,505H00H00H03H00H02HBUFDD:定义双字,其后每个操作数占4个字节;若仅保留单元,不初始化,用?代替初值;若数据重复,用nDUP()代替,n为重复次数。STRINGDB‘HELLO!’ARRAYDB100DUP(?)6个字节的存储单元,内为各字符对应的ASCII码,字符串用单引号标识保留100个字节,首地址为ARRAY,不初始化,即100个字节内均为随机值DATA1DB100DUP(‘AB’)初始化200个字节,内有100个41H,42H使用汇编语言定义的伪操作命令是:VALDB93DUP(5,2DUP(1,2DUP(3),4))则在VAL存储区前10个字节单元的数据是:5,1,3,3,4,1,3,3,4,5若定义DB1,2,5DUP(0,1,2DUP(3)),则在存储区前7个单元的数据是:1,2,0,1,3,3,0三、等值伪操作名字EQU表达式名字=表达式给名字定义一个值或其他符号名或一条可执行语句,在汇编时,凡是出现该名字的地方就用定义的数据替代。用EQU赋值的名字不能重新赋值,但可用PURGE释放后重新定义。TIMES
EQU50BUFDBTIMESDUP(?)等效于:BUFDB50DUP(?)ALPHAEQU256BETA=ALPHA-2DATASEGMENTADW3BDW4LEQUB-ADATAENDS03H00H04H00HDS:0000H数据段L为常量,不占空间,值为2变量在数据段出现,一般为偏移量,在程序段出现,为存储空间的内容。MOVAX,AMOVBX,BADDAX,BX;AX:3;BX:4;AX:7DATASEGMENTADW3,7BDW14LEQUBXDWBYEQUB-ADATAENDS03H00H07H00H0EH00H04H00HDS:0000H数据段;L:B;Y:0004HMOVAX,LMOVAX,XMOVAX,AMOVAX,A+2MOVBX,Y;AX:000EH;AX:0004H;AX:0003H;AX:0007HMOVAX,B;X:0004H;BX:0004H第三节汇编语言运算符汇编语言运算符:是编译程序在编译时计算的,与运算指令不同,指令是在程序运行时计算的。一、算术运算符+,-,*,/,MOD,SHL,SHRMOVAX,A+B二、逻辑运算符AND,OR,XOR,NOTCEQUB-AANDAX,CANDOFH三、关系运算符EQ,NE,LT,GT,LE,GElessthan,greatthan
结果产生一个逻辑值,真为0FFFFH,假为0000HMOVAX,((choiceLT20)AND5)OR((choiceGE20)AND6)注意:算术运算符总可以用于数字操作,其结果也是数字的。当应用于存储器操作数时,只有+,-运算符有意义;逻辑运算符的操作数也必须是数字,存储器操作数不能进行逻辑运算;关系运算符连接的两个操作数,必须都是数字的或是在同一段内的存储器地址。四、值返回符1)$运算符$:当前地址偏移量的值BLOCKDB‘HELLO!’NUMEQU$-BLOCKHELLO!BLOCK$;NUM为6STR1DW‘AB’STR2DB16DUP(?)CNTEQU$-STR1……MOVCX,CNTMOVAX,STR1HLTSTR1STR2BA;CX为18;AX为4142H$ABSTR1DW4142HSTR1DB41H,42HDATASEGMENTNAEQU15NBEQU10NCDB2DUP(4,2DUP(5,2))CNTDB$-NCCWTDW$-CNTNDDWNCDATAENDS设数据段定义如下:从DS:0000H开始至CNT单元之前存放的数据依次为:________;ND单元中的值为_________;CWT单元中的值为________;CNT单元中的值为_____。4,5,2,5,2,4,5,2,5,20000H10AH04H05H02H05H02H04H05H02H05H02H0AH01H00H00H00HSEG和OFFSETSEG:求标号或变量的段基址OFFSET:求标号或变量的距段首址的偏移量DATASEGMENTADB12BDW23,25DATAENDS……MOVBX,OFFSETBMOVAX,SEGBLEABX,B;BX:0001H;AX:DS值;BX:0001H与MOVBX,OFFSETBDATASEGMENTTABLEDW10,20,30,40,50ENTRYDW3DATAENDS……MOVBX,OFFSETTABLEADDBX,ENTRYMOVAX,[BX]0AH00H14H00H1EH00H28H00H32H00H03H00H;0000H;BX:3;AX:1E00HBX3)TYPE标号或符号的类型值对变量:表示变量的字节数
DB1,DW2,DD4对标号:表示过程或指令地址的调用类型
(NEAR)-1或(FAR)-2DATASEGMENTADB12BDW23,25DATAENDS……MOVAX,TYPEAMOVBX,TYPEB;AX:0001H;BX:0002H4)LENGTH和SIZELENGTH:对DUP情况下,变量的项数或元素个数,
在其他情况下该项属性为1;SIZE:对操作数分配的字节数。
SIZE=LENGTH×TYPEADB‘1234’BDW5DUP(2,3DUP(0))CDW‘AB’,‘C’,‘D’L1:MOVAL,TYPEBMOVBL,LENGTHBMOVAH,SIZEAMOVBH,SIZECMOVCL,TYPEL1MOVCH,SIZEB;AL:2;BL:5;AH:1;BH:2;CL:0FFH;CH:0AHCDW‘ABE’,‘C’,‘D’正确与否?对于下面的数据定义,各条MOV指令单独执行后,请填充有关寄存器的内容:
TABLE1DB?TABLE2DW20DUP(?)TABLE3DB‘ABCD’……MOVAX,TYPETABLE1MOVBX,TYPETABLE2MOVCX,LENGTHTABLE2MOVDX,SIZETABLE2MOVSI,LENGTHTABLE3;AX:1;BX:2;CX:20;DX:40;SI:15)HIGH和LOWHIGH:
对操作数取高字节;LOW:
对操作数取低字节。NUMEQU0CDEFH……MOVAH,HIGHNUMMOVAL,LOWNUM;AH:0CDH;AL:0EFH五、属性运算符用来给指令中的操作数指定一个临时的属性,而暂时忽略操作数定义时的属性。1)PTR定义操作数为新的类型新类型PTR操作数操作数可以是存储器的地址或标号名F1DW1234HF2DB23H,56H,18H……MOVAL,BYTEPTRF1MOVAX,WORDPTRF2;AL:34H;AX:5623H18H56H23H12H34HF2F1DAT1DB12H,34HDAT2DB56H,78H……MOVAX,WORDPTRDAT1CMPAX,WORDPTRDAT2JAL1MOVBX,WORDPTRDAT2MOVWORDPTRDAT2,AXMOVWORDPTRDAT1,BXL1:HLTDAT1单元的值是:__________;AX:3412H;7856H56H2)THIS指定新类型像PTR一样可用来建立一个特殊类型的存储器地址操作数,而没有为它分配存储器。新的存储器操作数的段和偏移量部分就是下一个能分配的存储单元的段和偏移量。F1EQUTHISBYTEF2DW4321H,2255H……MOVAL,F1MOVAX,F2THIS类型名22H55H43H21HF2F1;AL:21H;AX:4321HF1和F2具有相同的段基地址和偏移地址,但类型不同。3)段超越强迫当前指令的操作数按指定的段基地址寻址。MOVAX,ES:[BX]4)SHORT用于无条件转移指令JMP,通知编译器,转移的目标地址在-128~+127之间。JMP标号;是三字节指令JMPSHORT标号;是两字节指令第四节汇编语言程序汇编语言编写的程序也跟高级语言类似,程序结构分三种:顺序、分支、循环;较复杂的程序也应该是由众多子程序组成的,每个子程序是一个过程,在程序中被显式地调用。变量等数据部分被定义在数据段,所有程序都要显式地定义堆栈段。汇编程序的每一条指令都与机器语言一一对应,因此,汇编生成的可执行文件代码少,适合于实时控制,但由于语法成分很少,不适合于复杂的算法、运算。汇编程序主要的调试环境是DOS系统下的DEBUG程序。程序设计步骤1.分析问题2.建立数学模型3.确定算法4.绘制程序流程图5.内存分配(指令或伪指令)6.编制程序7.程序调试顺序结构程序例:自然数0~9的平方表,存在内存TABLE开始的连续10个单元中,现XAD单元存有任意一自然数(0X<10),查表求X的平方,存入YAD单元中。解:X2
的值的地址:
TABLE表的首地址+X0000H00001H10002H40003H90004H160005H250006H360007H490008H640009H81DATASEGMENT
数据段内容DATAENDS
CODESEGMENTASSUMECS:CODE,DS:DATASTARTPROCFARPUSHDS;将DS入栈
MOVAX,0000H;AX置零
PUSHAX;将0入栈
主程序RETSTARTENDPCODEENDSENDDATASEGMENTTABLEDB0,1,4,9,16,25,36,49,64,81XADDB8YADDB?DATAENDS
0000H00001H10002H40003H90004H160005H250006H360007H490008H640009H81000AH8000BH?0000H00001H10002H40003H90004H160005H250006H360007H490008H640009H81000AH8000BHMOVAX,DATAMOVDS,AX;初始化DSLEABX,TABLE;表的首址送BXMOVAH,0;AH送0
MOVAL,XAD;将X送ALADDBX,AX;求X平方值的地址MOVAL,[BX];X平方值送ALMOVYAD,ALBXBX=BX+AX64如何用查表指令(XLAT)完成?例:编程求函数y=((a+b)*c-d)/e,其中a、b、c、d、e依次存放在VARA、VARB、VARC、VARD、VARE单元,结果存放在VARY单元。解:首先定义存储单元,然后在主程序中依次实现……VARAVARBVARCVARDVAREVARY……DATASEGMENTVARADB6VARBDB7VARCDB8VARDDB9VAREDB10VARYDB?DATAENDS
……VARA6VARB7VARC8VARD9VARE10VARY?……MOVAL,VARAADDAL,
VARB;a+b->ALIMULVARC
;(a+b)*c->AXMOVBH,0MOVBL,VARD;d->BXSUBAX,BX;(a+b)*c-d->AXIDIVVAREMOVVARY,AX……VARA6VARB7VARC8VARD9VARE10VARY?……;AX:09H,DX:05H分支结构程序设计可以有两种形式,如图所示,它们分别相当于高级语言程序中的IF-THEN-ELSE语句和CASE语句,它们适用于要根据不同条件做不同处理的情况。实现方法:在产生分支之前,通常用比较、测试的办法在标志寄存器中设置相应的标志位,然后再选用适当的条件转移指令,以实现不同情况的分支转移。例:符号函数:(-128≤X≤+127)设任意给定的X存放在XX单元,计算出函数Y值要求存放在YY单元。例:符号函数:DATA SEGMENT
XX DB 0F0HYY DB ?DATA ENDS CODE SEGMENT ASSUMECS:CODE,DS:DATASTART PROC FAR PUSH DSSUB AX,AX PUSH AXMOV AX,DATA MOV DS,AX
MOV AL,XX CMP AL,0 JGE BIGR MOV AL,0FFH MOV YY,AL;AL=-1 RET BIGR: JE EQUL MOV AL,1;AL=1EQUL: MOV YY,AL
RET START ENDP CODE ENDS END START实现方法:用地址表法。思路:将各分支程序的入口地址依次罗列形成一个地址表,让BX指向地址表的首地址,从键盘接收或其他方式获取要转到的分支号,再让BX与分支号进行运算,使BX指向对应分支入口地址,最后即可使用JMPWORDPTR[BX]
或JMPDWORDPTR[BX]
指令实现所要转到的分支例:根据AL(1~8)中的值,转移到不同分支(R1~R8)。解:1、建立分支地址表DATASEGMENTBRTAB DWR11,R12 DWR21,R22 DWR31,R32 …… DWR81,R82DATAENDS
分支1偏移地址R11分支1段地址R12分支2偏移地址R21分支2段地址R22分支3偏移地址R31分支3段地址R32…………分支8偏移地址R81分支8段地址R82解:2、实现分支转移方法1:
LEABX,BRTABGTB: RCRAL,1 JC GETAD ADDBX,4 JMPGTBGETAD:
JMPDWORDPTR[BX]
分支1偏移地址R11分支1段地址R12分支2偏移地址R21分支2段地址R22分支3偏移地址R31分支3段地址R32…………分支8偏移地址R81分支8段地址R82例:根据AL(0~7)中的值,转移到不同分支(R1~R8)。方法2:LEABX,BRTABMOVAH,0MUL04HADDBX,AXJMPDWORDPTR[BX]
分支1偏移地址R11分支1段地址R12分支2偏移地址R21分支2段地址R22分支3偏移地址R31分支3段地址R32…………分支8偏移地址R81分支8段地址R82BX例:根据AL(0~7)中的值,转移到不同分支(R1~R8)。解:2、实现分支转移循环结构程序设计1.设置循环的初始状态设置循环次数的计数值,以及循环体正常工作的初始状态等2.循环体由循环的工作部分及修改部分组成。3.循环控制部分循环程序设计的关键,每一个循环程序必须选择一个循环控制条件来控制循环的运行和结束,通常有两种方法控制循环:用计数控制循环,用条件控制循环
LOOPL1=DECCX
JNZL1先判断条件,然后执行循环体。DO-WHILE结构先执行循环体,然后判断条件。DO-UNTIL结构特点:至少执行一次循环体。赋初值条件循环体修改YN开始赋初值循环体修改条件?NY开始例:显示以0结尾的字符串。STRDB'Letushaveatry!',0 MOVBX,OFFSETSTRAGAIN: MOVDL,[BX] CMPDL,0 JZ
DONE
;为0结束
MOVAH,2 ;调用DOS功能的2号功能 INT21H;不为0,显示
INCBX ;指向下一个字符
JMPAGAINDONE: ……例:求S=1+2+3+4+……+100解1:
MOVCX,100 MOVAX,0 MOVBX,1AG: ADDAX,BX INCBX LOOPAG MOVSUM,AX解2:
MOVCX,99 MOVAX,1 MOVBX,2AG: ADDAX,BX INCBX LOOPAG MOVSUM,AX例:从给定串中寻找最大的值,并放到MAX单元.元素放在BUFFER开始的单元中。解:分析:CX:循环比较次数,循环次数=数据个数-1BX:数据指针LOOP:循环控制开始BX元素表首地址CXN-1BXBX+1AL=[BX]?AL、[BX]中的数交换CXCX-1CX=0?YN暂停YN参考程序:BUFFERDB21,33,45,67,98,10,…COUNTEQU$-BUFFERMAXDB?MOVCX,COUNT-1MOVBX,OFFSETBUFFERMOVAL,[BX]DON:INCBX;指向下一个数
CMPAL,[BX];AL-[BX]
JAP1;大于转
MOVAL,[BX];交换
P1:LOOP
DONMOVMAX,AL……BUFFER213345679810COUNT6MAX?例:求N!分析:N等于0:
N!=1N不等于0:N!=N*(N-1)*(N-2)…*3*2*1AX=NBX=N-1AX<=1?AX=1退出AX=AX*BXBX=BX-1BX=0?YYNN程序段:
MOV AX,N CMP AX,1
JA NOZ
MOV AX,1
JMP
OKNOZ:
MOVBX,N-1LP1: MULBX DECBX JNZLP1OK: MOVYY,AXAX=NBX=N-1AX<=1?AX=1退出AX=AX*BXBX=BX-1BX=0?YYNN例:试编制程序把BX寄存器内的二进制数以十六进制形式在屏幕上显示出来。分析:1、二进制到十六进制显示必须转换成ASCII码,即0-9、41H-46H(A~F)2、BX寄存器为16位,共有4组4位二进制位,可用一个循环次数为4的循环逐一显示。3、取出四位二进制位可以用循环左移指令,再将高四位与0FH相与。
MOVCH,4 LOOP1:MOVCL,4 ROLBX,CL;BX循环左移四位
MOVAL,BL ANDAL,0FH;取其低四位
ADDAL,30H;转换为ASCII码
CMPAL,3AH JL
DISP
;小于10,转换完毕
ADDAL,7;大于等于10,换到A~FDISP: MOVDL,AL MOVAH,2 INT 21H
;显示
DECCH ;循环次数减一
JNZ
LOOP1
;循环完成否继续循环
设循环次数开始BX循环左移四位低四位+30H是A~F?+7显示循环次数够?退出例:设计一个100ms的软件延时程序。采用多重循环程序,内循环完成10ms的延时,外层循环10次即可。CODE SENGMET ASSUME CS:CODESTART: MOV DL,10DELAY1: MOV CX,2800HDELAY2: LOOPDELAY2 DEC DL JNZ DELAY1
MOV AH,4CH INT 21HCODE ENDS END START以5MHz主频为例,LOOP指令执行需18个时钟周期。10000*5/18=2800子程序设计子程序:相对主程序而言,是被主程序调用的程序.把功能相对独立的程序段单独编写和调试,作为一个相对独立的模块供程序使用,就形成子程序子程序调用示意图:
主子子子1子2主主主汇编语言中,子程序要用一对过程伪指令PROC和ENDP声明,格式如下:
过程名
PROC[NEAR/FAR] …… ;过程体 过程名 ENDP可选的参数指定过程的调用属性。没有指定过程属性,则采用默认属性NEAR属性(段内近调用)的过程只能被相同代码段的其他程序调用FAR属性(段间远调用)的过程可以被相同或不同代码段的程序调用子程序设计利用寄存器传递参数
主程序将参数保存到寄存器中,子程序通过访问寄存器来取得变量。
子程序将参数保存到寄存器中,主程序通过访问寄存器来取得变量。例:从键盘接收一个十进制数,将其以十六进制的形式显示出来。
分析:1)从键盘接收十进制数,键盘输入的是ASCII码,要先转换成十六进制30H-39H,如果输入的不是数字,还要加以判断。若输入的是多位数,也要加以判断,并累加计算。2)输入后在下一行显示十六进制数,应当有回车换行3)将十进制数转换成十六进制数后,再逐一转换成ASCII码显示CODESEGMENTASSUMECD:CODE,DS:DATAMAINPROCFAR
START: PUSH DS MOV AX,0 PUSH AX CALL DECIN
CALL CRLF
CALL BINTODEC
RETMAIN ENDPDECINPROCNEARMOV BX,0NEWCHAR:MOV AH,1;有回显键盘输入INT 21H;AL=键输入ASCII码SUB AL,30HJL EXITCMP AL,9JG EXITCBWXCHGAX,BXMOV CX,10MUL CXXCHGAX,BXADD BX,AXJMP NEWCHAREXIT:RETDECINENDPCRLF PROC NEAR MOVDL,0DH;回车ASCII码
MOVAH,2 INT 21H;显示回车
MOVDL,0AH;换行ASCII码
MOVAH,2 INT 21H;显示换行
RETCRLF ENDPBINTODECPROCNRARMOV CH,4NEXT2:MOV CL,4ROL BX,CLMOV AL,BLAND AL,0FHADD AL,30CMPAL,3AHJL PRINTADD AL,7PRINT:
MOV DL,AL MOV AH,2 INT 21H DEC CH JNZ NEXT2
RETBINTODECENDP例:从键盘接受一个十六进制数(0~0FFFFH,正数),转换为十进制数并在屏幕上显示出来分析:1)从键盘接受十六进制数,用DOS的1号功能调用逐一接收,每接收完一个再接收下一个时应将先前的左移四位。2)接收完毕后最大为65536,显示时可以将此数除以10000,1000,100,10,1将商逐一显示即可。CODESEGMENTASSUMECD:CODE,DS:DATAMAINPROCFAR
START: PUSH DS MOV AX,0 PUSH AX CALL HEXIBIN CALL CRLF CALL BINIDEC
RETMAIN ENDPHEXIBINPROCNEARMOV BX,0NEW:
MOV AH,1INT 21HSUB AL,30HJL EXIT ;CMP AL,10DJL ADD_TOSUB AL,07HCMP AL,0AHJL EXITCMP AL,10HJGE EXITADD_TO:MOV CL,4SHL BX,CLMOV AH,0ADD BX,AXJMP NEWEXIT: RETHEXIBINENDPCRLF PROC NEAR MOV DL,0DH;回车ASCII码
MOV AH,2 INT 21H;显示回车
MOV DL,0AH;换行ASCII码
MOV AH,2 INT 21H;显示换行
RETCRLF ENDPBINIDECPROC NEARMOV CX,10000DCALL DEC_DIVMOV CX,1000DCALL DEC_DIVMOV CX,100DCALL DEC_DIVMOV CX,10DCALL DEC_DIVMOV CX,1DCALL DEC_DIVRETDEC_DIV PROCNEAR MOV AX,BX MOV DX,0 DIV CX MOV BX,DX MOV DL,AL ADD DL,30H MOV AH,2
INT 21H RETDEC_DIV ENDPBINIDEC ENDP利用共享变量(全局变量)进行参数传递例:子程序设计:冒泡排序规则:表中相邻两元素一一比较,并把大值元素向下交换,直至表尾(大值元素下沉),此时,称为一次冒泡(程序中一次大循环)。以后重复冒泡排序,直至最小元素冒到表顶为止。分析:假设有N个元素,则需要N-1次冒泡,每次冒泡需要的比较次数=N-1-J,J为完成的冒泡次数.子程序名:ARRAY子程序功能:冒泡排序入口:TAB=数据首址,N=数据项数出口=显示排好序的字符子程序设计DATASEGMENTTABDB10,23,5,16,9;定义字符串
N=$-TAB
;N在此等于5DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTAR:MOVAX,DATAMOVDS,AX;初始化数据段
CALL
ARRAY
;调用子程序
RET
在此定义子程序
CODEENDSENDARRAYPROCNEAR
MOVDL,N-1;外循环次数
MOVBX,0UPPER: MOVCX,N-1 SUBCX,BX;内循环次数
MOVSI,0
INNER: MOVAL,TAB[SI] INCSI CMPAL,TAB[SI] JBEDON
XCHGAL,TAB[SI] MOVTAB[SI-1],ALDON:
LOOPINNERINCBX DECDLCMPDL,0 JNZ
UPPER
OK:RETARRAYENDP
第五节DOS功能调用操作系统管理计算机,为用户提供与CPU对话的接口,也就是提供使用键盘和显示器的通道。操作系统同时管理设备、文件,这样,用户不需要具体掌握这些接口的地址,输入输出数据的格式,直接执行操作系统提供的命令就可以了。比如DOS命令:DIR,TYPECOPY等。这是用户在操作系统层面上的调用。在运行用户程序时,DOS将操作权交给了用户程序,用户就无法再去执行DOS的操作命令了,这时,用户程序需要与键盘、显示器等系统资源打交道该怎么办?在高级语言中,在这种情况下都是调用编译系统提供的库函数,也即编译系统已把输入输出等操作功能做成函数的形式,用户只要依据函数的格式进行调用即可。在汇编程序中,如果用户程序要与输入输出设备打交道,就要调用现成的程序,这些程序是DOS系统的一部分,随DOS系统驻留内存,用户需要按照这些程序要求的接口格式调用。这些完成不同功能的子程序是以中断服务程序的方式提供的。这些功能按不同的类别分成许多组,分别有不同的中断入口,在汇编程序中最常用的是INT21H中断入口,也称为DOS系统功能调用。这个中断入口中有90多个小程序,每个小程序都被编上号,固定完成某一种功能,调用时有一定的格式,因为对某一个小程序而言,输入条件(入口参数)和输出结果(出口参数)的格式都是固定的。用户在使用时,既要给出小程序的编号(AH),又要按照其提供的格式进行调用,才能正确完成操作。系统功能调用的小程序有90多个,在这里只介绍与输入输出有关的一部分。1)在显示器上显示单个字符(2号功能)功能:在屏幕的光标处显示单个字符入口参数:要显示字符的ASCII码放在DL中出口参数:无MOVDL,‘A’MOVAH,2INT21H;提供调用功能号;系统功能调用;在屏幕光标处显示字符A运行至此,屏幕上当前光标处显示字符A2)在屏幕上显示字符串(9号功能)功能:在屏幕上当前光标处输出存储在内存数据段的一串字符串,该字符串以‘$’结束。入口参数:DS:DX指向欲显示字符串的首址出口参数:无DATASEGMENTSTRINGDB‘Iamastudent.$’DATAENDS……MOVDX,OFFSETSTRINGMOVAH,9INT21H;指向字符串首址;提供调用功能号;系统功能调用3)带显示的键盘输入(1号功能)功能:等待键盘输入,直到按下一个键。入口参数:无出口参数:键入键的ASCII码放在AL中,并在屏幕上显示该键。MOVAH,1INT21HMOV[2000H],AL……;提供调用功能号;系统功能调用程序运行到此停下,等待用户键盘输入用户从键盘键入的键的ASCII码进入AL中4)不带显示的键盘输入(7号功能)功能:等待键盘输入,直到按下一个键。入口参数:无出口参数:键入键的ASCII码放在AL中,但在屏幕上没有显示,常用于输入密码。MOVAH,7INT21HMOV[2000H],AL……;提供调用功能号;系统功能调用程序运行到此停下,等待用户键盘输入用户从键盘键入的键的ASCII码进入AL中该功能与1号功能类似,只是输入的字符不在屏幕上显示5)字符串输入(10号功能)功能:等待从键盘输入一串字符到存储区的数据段,直到按下回车结束输入。入口参数:DS:DX指向接收字符串的内存地址的首址,该地址的第一个字节是由用户设置的可输入字符串的最大字符数(含回车)出口参数:存放输入字符串,存储区的第二个字节是实际输入的字符数(不含回车),实际输入的字符串从该存储区的第三个字节处开始存放。DATASEGMENTBUFDB20,20DUP(?)DATAENDS……LEADX,BUFMOVAH,0AHINT21H14H程序运行到此停下,等待用户键盘输入若输入ABCD<CR>后BUFDX04H41H42H43H44H实际字符个数开始存放6)程序结束,返回DOS(4C号功能)功能:将控制权移交DOS。入口参数:无出口参数:无MOVAH,4CHINT21H在屏幕上显示What’syourname?,用户输入自己的名字###后显示:Welcome###。
DATASEGMENTMEGDB‘What’syourname?’,10,13,’$’MEG1DB'Welcome$'BUFDB30,?,30DUP(0)DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATAMAINPROCFARSTART:MOVAX,DATAMOVDS,AXLEADX,MEGMOVAH,9INT21HLEADX,BUFMOVAH,10INT21HLEADX,MEG1MOVAH,9INT21HXORBH,BHMOVBL,BUF+1MOV[BX+BUF+2],‘$’LEADX,BUF+2MOVAH,9INT21HMOVAH,4CHINT21HMAINENDPCODEENDSENDSTART;输出字符串;接受姓名;输出Welcome;输出姓名;返回DOS输入缓冲区以‘$’结尾显示字符串后,回车,换行INCSICMPAL,0DH___________________________JNELOPMOVAH,4CHINT21HCODEENDSENDSTART下面程序从键盘重复接收一字符送BUFF开始的单元,直到接收到回车符0DH为止。DATASEGMENTBUFFDB128DUP(0)DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AX_______________LOP:_______________INT21HMOV[SI],ALLEASI,BUFFMOVAH,1第六节宏指令在汇编语言书写的
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 英国外贸协议书时间
- 协议书履约保证金
- 签协议书需要什么
- 宅基地赠与协议书范本
- 赠险协议书模板
- 红人电子协议书
- 合作股权分配协议书
- 分家协议书单方能反晦
- 2025YY公司行政人员劳动合同
- 木结构耐久性分析-洞察与解读
- 2025年河北唐山市芦台经济开发区公开招聘区属国有企业工作人员18人笔试模拟试题及答案解析
- 2024年新高考Ⅰ卷英语真题(原卷+答案)
- 2025山东东营公安招录辅警392人考试参考试题及答案解析
- 2025四川宜宾市退役军人事务局招聘临聘人员2人考试参考题库及答案解析
- 高考语文 热点04 现代文阅读II之理论与文本互证类题(解析版)
- 预制混凝土检查井采购合同模板
- 外贸会计自学课件
- 2025年中小学《国庆节、中秋节》放假通知及安全提示
- 致敬 9.3:一场阅兵一部民族精神史诗
- (完整版)室外散水专项方案
- 智能物流行业智能化运输装备应用前景研究报告
评论
0/150
提交评论