




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第4章汇编语言程序设计4.1汇编语言概述
4.2汇编语言程序实现
4.3汇编语言程序设计方法及应用4.4汇编语言程序设计举例
汇编语言〔AssemblyLanguage〕是一种采用指令助记符、符号地址、标号、伪指令等符号编写程序的程序设计语言。用汇编语言编写的程序称为汇编语言源程序〔SourceProgram〕。一般情况下,一个助记符对应一条机器指令,所以汇编语言也是面向机器的语言。4.1汇编语言概述源程序的结构与组成【例题4.1】实现:123+456→sum的源程序
CODE SEGMENT;语句6
ASSUMECS:CODE,DS:DATAMAINPROCFAR;语句8START:PUSHDS;语句9
……….;
RET;语句17MAINENDP;语句18CODEENDS;语句19数据段代码段DATASEGMENT;语句1ADW123;语句2BDW456;语句3SUMDW?;语句4DATAENDS;语句5ENDSTART
;语句20★[名字]指令/伪指令[操作数1[,操作数2…]]★段=∑语句1.源程序组成★源程序=∑段段一个汇编语言源程序中,代码段是不可缺少的,其它段〔数据段、堆栈堆、附加段〕视具体情况而定。该程序共有2个段:行1~行5为一段、行6~行19为一段DATA、CODE分别为2个段的名字。每一段有明显的起始语句与结束语句,这些语句称为“段定义〞语句。代码段的第一个语句ASSUME(本例中行7),用于明确段与段存放器的关系。本程序中DATA是数据段、CODE是代码段。段:数据段、堆栈段、附加段、代码段语句
源程序由语句组成。汇编语言源程序语句可以分为:
指令语句伪指令语句宏指令语句语句:★指令性语句,由CPU执行,如:语句8~语句17。★指示性语句,指示汇编,如语句1、5、6、19、20。名字:段名,如:DATA、CODE
变量名,如:A、B、SUM
过程名,如:MAIN
标号名,如:START名字汇编语言源程序中的变量名、标号、常量名、段名、宏名等统称为“名字〞。
段名,如:DATA、CODE
变量名,如:A、B、SUM
过程名,如:MAIN
标号名,如:START1)组成名字的合法字符有:●字母〔不分大小写〕;●数字0~9;●特殊符号〔“?〞,“:〞,“@〞,“_〞,“$〞〕。2)名字以字母开头。3)不能把保存字用作名字。(1).名字命名规那么(2).名字属性1)变量名2)段名:该段起始位置的段地址值
段属性:变量所代表的数据区所在段的段基址;偏移量:变量所代表的数据区首字节所在段内偏移地址;类型:BYTE、WORD、DWORD、DQ、DT长度:变量所代表的数据区中数据元素的个数。规模:变量所代表的数据区中数据所占空间大小,以字节计。3)过程名或标号名4)常量名:代表一常数段属性:过程起始位置或标号处段地址值偏移量:过程起始位置或标号处偏移地址值类型:NEAR、FAR用于程序跳转4.1.2汇编语言伪指令1.数据定义伪指令
[变量名]数据定义伪指令操作数1[,操作数2…]
DB、DW、DD、DQ、DT字节、字、双字、4字、5字的变量。(1)数字常量:十进制、八进制、十六进制、二进制等,缺省形式是十进制;(2)字符常量,用单引号括起来,被存储的是该字符的ASCII码;(3)符号常量,必须是预先已定义的符号;(4)符号“?〞,表示预留空间,内容不定;
(5)DUP,表示内容重复的数据。具体形式为:次数DUP(被重复的内容)操作数:【例】D_ADB10,‘A’,‘BC’D_BDW1234HD_CDQ5678H
D_A
0AH
41H
42H
43H
D_B
34H
12H
D_C
78H
56H
0
0
0
0
0D_C+7
0
(1)DB定义的数据,每个数据元素占据1个存储单元;
DW定义的数据,每个数据元素占据2个存储单元;(2)字数据存储时,低字节存储在低地址单元中,高字节存储在高地址单元中;(3)字符被存放时为它的ASCII码,
例‘A’的ASCII码为41H;(4)符号地址具有以下关系:
D_B=D_A+3D_D=D_B+2=D_A+6
注:ORG100HD_EDB3DUP(?)EVEND_FDWD_ED_GDB2DUP(1,3,4)D_HDW$+2变量内容偏移地址D_E?100
?101
?102103D_F00H10401H105D_G1106310741081109310A410BD_H0EH10C01H10D下一个存储位置从偶地址开始己定义变量,取该变量偏移地址代表当前偏移地址2.符号定义伪指令(1)EQU格式:名字EQU表达式
例:
VBEQU64×1024;VB代表数值表达式的值
AEQU7BEQUA-2注意:
1.如果表达式中有变量,应在该语句前给出该变量的定义;
2.EQU语句不能给某一变量重复定义;
3.VB、A、B不占用内存(2)等号=格式:名字=表达式功能:与EQU根本相同,区别是它可以对同一个名字重新定义。例:COUNT=10MOVAL,COUNT;…COUNT=5;可重复定义…例:ABCDW?
A1EQUBYTEPTRABC;A1是ABC的第一个字节
A2EQUBYTEPTRABC+1或A2EQUA1+1MOVAL,A1MOVAH,A2例,可以如下处置:③
MOVAX,WORDPTROPER1+1;AX=3402HMOVAL,BYTEPTROPER2;AL=34HMOVAL,BYTEPTROPER2+1;AL=12H
例:
OPER1DB1,2OPER2DW1234H,5678H
…MOVAX,OPER1+1MOVAL,OPER2;这里类型不匹配(3)LABEL格式:变量/标号LABEL类型功能:定义变量或标号的类型,而变量或标号的段属性和偏移属性由该语句所处的位置确定。变量的类型有:BYTE、WORD、DWORD、DQ、DT;标号的类型有:NEAR、FAR。【例】利用LABEL使同一个数据区有一个以上的类型及相关属性。AREAWLABELWORD;AREAW与AREAB指向相同的数据区,AREAW类型为字,而
AREAB类型为字节AREABDB100DUP(?)……MOVAX,1234HMOVAREAW,AX;(AREAW)=1234H……MOVBL,AREAB;BL=34H
3.段定义伪指令段名SEGMENT[定位类型][组合类型][‘类别’]
…段名ENDSBYTE:××××××××××××××××B,即段可以从任何地址开始;WORD:×××××××××××××××0B,即段的起始地址必须为偶地址;PARA:××××××××××××0000B,即段从节(PARAGRAPH)边界开始,每16个字节为1小段,所以,其起始地址必为16的倍数。PAGE:××××××××00000000B,即段从页边界开始,每256个字节为1页,所以,其起始地址必为256的倍数。*定位类型:说明段的起始地址应有怎样的边界值:*组合类型:说明程序连接时的段合并方法
1PUBLIC:将同类别名段组装在一起形成一个逻辑段;2STACK:与PUBLIC一样,只用于堆栈段。在汇编及连接后,系统自动为SS及SP分配值,在可执行程序中,SP初值指向栈底。3COMMON:同名段从同一个内存地址开始装入。所以,各个逻辑段将发生覆盖。连接以后,该段长度取决于同名段中最长的那个,而内容有效的是最后装入的那个。4MEMORY:与PUBLIC同义,只不过MEMORY定义的段装在所有同名段的最后。假设连接时出现多个MEMORY,那么最先遇到的段按组合类型MEMORY处理,其他段组合类型按PUBLIC处理。5PRIVATE:不组合,该段与其它段逻辑上不发生关系,即使同名,各段拥有各自的段基值。[缺省值]6ATexp:段地址为表达式exp的值(长度为16位)。此项不能用于代码段。
当几个程序模块进行连接时,其中具有相同类别名的段,按出现的先后顺序被装入连续的内存区。没有类别名的段,与其它无类别名的段一起连续装入内存。类别:类别的作用是在连接时决定各逻辑段的装入顺序。类别名必须用单引号括起来。ASSUME段存放器名:段名[,段存放器名:段名…]ASSUME:用于明确段与段存放器的关系说明:该伪指令出现在码段中;本伪指令只是指示各逻辑段使用段存放器的情况,并没有对段存放器的内容进行赋值。DS、ES的值必须在程序段中用指令语句进行赋值,而CS、SS由系统负责设置,程序中也可对SS进行赋值,但不允许对CS赋值。例:ASSUMEDS:DSEG,CS:CSEG,ES:ESEG,SS:SESG例:ASSUMECS:CODE,DS:DATA,ES:DATA*【例】按下面要求,写出程序框架数据段从0E000H开始,其中有100字节的数组,其类型属性既是字又是字节;2.堆栈段从小段开始,段组名为STACK;3.代码段中指定段存放器,主程序从1000H开始,给有关段存放器赋值;4.程序结束。DSEGSEGMENTAT0E000HD_BYTEDB100DUP(?)D_WORDEQUWORDPTRD_BYTEDSEGENDSSSEGSEGMENTPARA‘STACK’DB200DUP(?)SSEGENDSCSEGSEGMENTORG1000HASSUMECS:CSEG,DS:DSEG,SS:SSEGMAINPROCFARXORAX,AXPUSHAXPUSHDSMOVAX,DSEGMOVDS,AX
……RETMAINENDPCSEGENDSENDMAIN4.模块定义和结束伪指令⑴NAME格式:NAME模块名功能:为源程序的目标程序指定一个模块名。如果程序中没有NAME伪指令,那么汇编程序将TITLE伪指令定义的标题名前6个字符作为模块名;如果程序中既没有NAME,又没有TITLE,那么汇编程序将源程序的文件名作为目标程序的模块名。格式:END[标号]功能:表示源程序的结束。标号指示程序开始执行的起始地址。如果多个程序模块相连接,那么只有主程序要使用标号,其它子模块只用END而不必指定标号。⑵END5、其它伪指令⑴对准伪指令EVEN格式:EVEN功能:使下一个分配地址为偶地址。说明:在8086中,一个字的地址最好为偶地址。因为8086CPU同样的存取一个字,如果地址是偶地址,需要一个读或写周期,如果是奇地址,需要2个读或写周期。所以,该伪指令常用于字定义语句之前。格式:ORG表达式表达式取值范围为:0~65535,无符号数功能:指定其后的程序段或数据块所存放的起始地址的偏移量。⑵定位伪指令ORG格式:RADIX表达式表达式取值为2~16内任何整数。功能:指定汇编程序使用的默认数制。缺省为十进制。【例】 MOVBX,0FFH;十六进制数要加后缀
MOVBX,178;十进制数不要加后缀
RADIX16;设置16进制为默认数制
MOVAX,0FF;十六进制数不要加后缀
MOVBX,178D;十进制数要加后缀⑶基数控制伪指令RADIX4.1.3汇编语句与运算符1、语句格式:[名字]操作[操作数][;注释]常量、变量和表达式组成由常量、变量和运算符组成
算法运算符+、-、*、/、MOD
逻辑运算符AND、OR、NOT、XOR
关系运算符EQ、NE、LT、GT、LT、LE、GE
分析运算符SEG、OFFSET、TYPE、LENGTH、SIZE
属性运算符PTR、THIS、SHORT
其它LOW、HIGH2、运算符例1)ARRAYDW1*2+3-4,56HMOVAX,ARRAY;汇编后为:MOVAX,12)MOVAL,7FHMOD2;汇编后为:MOVAL,13)MOVAH,15/4;汇编后为:MOVAH,3〔1〕算术运算符〔2〕逻辑运算符例1:MOVAH,11110000BMOVAL,NOTAH;MOVAL,00001111BMOVBL,AHORAL;MOVBL,11111111BMOVBH,AHXORAL;MOVBH,11111111B例2:从端口86H读取一个字节,高位屏蔽后从端口6送出。
PORTEQU86HINAL,PORTAND1AL,0FH;AND1为逻辑指令
MOVDX,PORTAND20FH;AND2为汇编运算符
OUTDX,AL〔3〕关系运算符关系运算符两边的操作数必须是两个数值或同一段中两个存储单元地址,运算结果应为逻辑值,结果为真,表示为0FFFFH;结果为假,那么表示为0。例:AEQU80HBEQU88HMOVAL,AEQBMOVAH,ANEBMOVBL,ALTBMOVBH,AGTB
MOVCL,ALEBMOVCH,AGEB〔4〕分析/数值返回运算符SEG变量或标号返回变量或标号的段地址OFFSET变量或标号返回变量或标号的偏移量TYPE变量或标号LENGTH变量SIZE变量返回变量或标号的类型值返回DUP定义的数据占据的单元数;非DUP定义的数据,返回1。返回DUP定义的数据占据的字节数;非DUP定义的数据,返回类型值。变量类型值:
DB:1,DW:2,DD:4,DQ:8,DT:10。标号类型值:NEAR:-1,FAR:-2。【例】数据定义如下:DATASEGMENTAT2000HBUF1DB0,1,2,3,4,5,6,7,8,9BUF2DW5DUP(0)DATAENDS那么:SEGBUF1=2000HSEGBUF2=2000HOFFSETBUF1=0000HOFFSETBUF2=000AHTYPEBUF1=1TYPEBUF2=2LENGTHBUF1=1LENGTHBUF2=5SIZEBUF1=1SIZEBUF2=10(5)属性运算符
属性运算符用来建立或改变已定义变量、内存操作数或标号的类型属性。属性运算符有:
PTR、THIS、SHORT1〕PTR类型PTR变量/标号典型应用之一:重新指定变量类型例:数据定义如下:BUFWDW1234H,5678H那么以下指令合法:MOVAX,BUFW;临时改变BUFW的字属性为字节属性MOVAL,BYTEPTRBUFW典型应用之二:指定内存操作数的类型例:INC[BX];汇编将指示出错
INCBYTEPTR[BX];正确
INCWORDPTR[BX][SI];正确分析:在存放器间接寻址、存放器相对寻址、基址变址寻址或相对基址变址寻址等内存寻址方式中,往往很难判断出操作数的类型属性,应对操作数类型加以说明。典型应用之三:与EQU一起定义一个新的变量变量或标号EQU类型PTR
例:BUFWDW1234H,5678HBUFBEQUBYTEPTRBUFW;BUFB的类型属性为字节,其它属性与BUFW一样。……MOVAX,BUFW;AX=1234HMOVAL,BUFB;AL=34H2)THIS格式:THIS类型可以像PTR一样建立一个指定类型的地址操作数,该操作数的段地址和偏移地址与下一个存储单元地址相同。
例:BUFB EQUTHISBYTEBUFWDW1234H,5678H…….MOVAX,BUFW;AX=1234HMOVBL,BUFB;BL=34HBUFB的偏移地址和BUFW完全相同,但它是字节类型;而BUFW那么是字类型。3)SHORT格式:
SHORT标号返回值:偏移量在-128~+127范围内的标号。说明:用于JMP指令。即:JMPSHORT标号,指明是短转移。4)其它字节别离运算符HIGH、LOW格式:HIGH表达式LOW表达式返回值:表达式值的高字节或低字节【例】CONSTEQU0ABCDHMOVAH,HIGHCONST;AH=0ABHMOVCL,LOWCONST;CL=0CDH运算符的优先级优先级运算符1()、[]、<>2LENGTH、SIZE、WIDTH、3PTR、OFFSET、SEG、TYPE、THIS4HIGH、LOW5*、/、MOD6+、-7EQ、NE、LT、LE、GE、GE8NOT9AND10OR、XOR11SHORT3.注释项注释项用来说明一段程序或一条或几条指令的功能,此项为可选项,不会影响程序的执行。好的注释,使程序容易读懂、便于维护。对编程者而言,注释项是一种“备忘录〞。写注释时,要注意注释不仅是对指令自身功能的说明,而更应从整体上说明该语句或一组语句所起的作用。
在循环程序的开始都有初始化程序,设置有关工作单元的初值:
MOVCX,100;将100送入CX MOVSI,0100H;将0100送入SI MOVDI,0200H;将0200送入DI这样注释没有说明它们在程序中的真正作用,应改为:
MOVCX,100;循环计数器CX置初值
MOVSI,0100H;源数据区指针SI置初值
MOVDI,0200H;目标数据区指针DI置初值例多个模块之间的参数传送:局部符号:在本模块中定义,在本模块中引用的符号外部符号:在某一模块中定义,在另一模块中引用的符号
PUBLIC符号EXTRN符号:类型
extrnproadd:far…………code1segmentstart:……callfarptrproadd
……code1endsendstart;proadd1.asmpublicproadd…………code2segmentproaddprocfar……retproaddendpcode2endsend;proadd2.asm*、PUBLIC与EXTRN
例:;proadd1.asmextrnproadd:fardatasegmentcommonarydw1,2,3,4,5,6,7,8,9,10countdw10sumdw?dataendscode1segmentmainprocfarassumecs:code1,ds:datastart:movax,datamovds,ax
callfarptrproadd
movah,4chint21hmainendpcode1endsendstart;proadd2.asmpublicproadddatasegmentcommonarydw1,2,3,4,5,6,7,8,9,10countdw10sumdw?dataends
code2segmentproaddprocfarassumecs:code2,ds:data
movax,datamovds,ax
pushaxpushcxpushsileasi,arymovcx,countxorax,axnext:addax,[si]addsi,2loopnextmovsum,ax
popsipopcxpopax
retproaddendpcode2endsend4.2
汇编语言程序实现汇编程序返回DOS方法1.标准方法
MAINPROCFARPUSHDSMOVAX,0PUSHAX
……RETMAINENDP
2.DOS功能调用方法
……MOVAH,4CHINT21H
4.3.1概述4.3.2顺序结构程序设计4.3.3分支结构程序设计4.3.4循环结构程序设计4.3.5子程序设计4.3.6*宏定义与使用4.3.7系统功能调用4.3汇编语言程序设计方法及应用(1)分析问题包括找出条件、问题特点、问题中的规律并归纳出数学模型。注意:有些问题不一定非要写出数学模型,或者根本写不出数学模型。但是,当有了一个数学模型之后,就可使用很多行之有效的计算方法。(2)确定算法指根据人们在解决实际问题时的逻辑思维中的常规推理,去找算法。如果已有数学模型,可以直接或间接利用一些现有的计算方法。1.程序设计步骤4.3.1概述(3)绘制流程图采用流程图:(1)使解题思路清淅,有利于理解和编制程序;(2)有利于修改程序和减少错误等;(3)对于一个复杂的问题,可以画多级流程图,先画出粗框图,再逐步求精,画出细框图。
流程图是程序算法的图形描述,即用图形的方式把解决问题的先后次序和程序的逻辑结构直观地、形象地描述出来;(4)分配存储空间及工作单元(包括存放器)8088/8086存储器结构要求存储空间分段使用。因此,数据段、堆栈段、代码段以及附加段要按需要分别定义。工作单元即可以设置在数据段或附加段中的某些存储单元,也可以设置在CPU内部的数据存放器中。
根据流程图和确定的算法逐条语句地编写程序,注意不同的机器有不同的指令系统。(5)编写程序(6)静态检查看程序是否具有所要求的功能;程序是否清晰易读;选用指令是否适宜;程序语法和格式上是否有错;指令中引用的符号、标号和变量是否认义正确;程序执行流程是否符合算法和流程图等等;适当考虑字节数要少,执行速度要快等。(7)运行调试静态检查可以发现一些问题,但毕竟还受到个人主观因素的影响。只有在机上运行通过并且结论正确的程序,才是正确的程序。事实上,即使一个非常有经验的程序员,也不能说程序一编就成功,特别是一些复杂的程序,必须经过调试、修改、再调试、再修改,反复屡次之后,才能得到一个比较满意的程序。【例】编程实现在100个无符号字节整数的数组中找出最大数。(1)分析问题本例中,有100个整数的数组,可以把它看作一个集合,记作{S}。在此集合中找出最大数,记为max{S}。(2)确定解决问题的算法人工方法:首先从第一个数据开始,一边看一边比较两个数的大小,看到较大数就记下,将较小数丢掉;再将此较大数与下一个数进行比较,始终将比较大的数记下,一直将数组中的数两两比较完毕,就能找到最大数。首先,建立一个数据指针指向数据区的首地址,将第一个数取到某个存放器中(例AL),与下一个数相比较,假设下一个数大,就将它存到AL中,替换掉原来的数;然后调整数据指针,将AL的数与此指针所指的数进行比较,再重复上述步骤,两两比较下去,直到比较完毕,结果AL中留下最大数。(3)算法、流程图开始初始化取第一个数到寄存器与下一个数比较
下一个数大?取大数到寄存器调整修改工作单元
查找结束?结束YNNY(4)存储设计及数据定义把数组存放在数据段中,并设置50个字节堆栈空间。利用BX存放器作数据指针,用CX作计数器,用AL暂存较大数。DSEGSEGMENT;定义数据段
ARRAYDBX1,X2……
COUNTDW$-ARRAY;计算数据个数DSEGENDSSSEGSEGMENTPARASTACK‘STACK’
;定义堆栈段
SDATDB50DUP(?)TOPEQULENGTHSDATSSEGENDS
CSEGSEGMENT;定义代码段
ASSUMECS:CSEG,DS:DSEG,SS:SSEGMAINPROCFAR;定义过程
START:PUSHDS;为返回DOS作准备
MOVAX,0PUSHAXMOVAX,DSEGMOVDS,AX;设置DSMOVAX,SSEGMOVSS,AX;设置SSMOVAX,TOPMOVSP,AX;设置SP初值
MOVBX,OFFSETARRAY;设置数据区指针首地址MOVCX,COUNT;设置计数器初值DECCX;设置比较次数MOVAL,[BX];取数入ALAGAIN:INCBX;指向数据区下一个数据CMPAL,[BX];两数比较JAENEXT;AL≥[BX],转NEXTMOVAL,[BX];否那么,把较大数取入ALNEXT:DECCX;全部数据比较完否?JNZAGAIN;否,转AGAINRET;全部比较完毕,返回DOSMAINENDPCSEGENDSENDSTART汇编语言的根本结构:2.结构化程序设计4.3.2顺序结构程序设计BCA顺序结构
顺序结构程序又称简单程序。这种结构的程序中无程序跳转指令、无循环指令,所有指令按其书写顺序逐条顺序执行,程序的执行路径从上到下只有一条。因此,顺序程序的设计只要依照步骤写出相应的指令即可。【例题4.3】将存储单元A中2个压缩BCD数拆成2个非压缩的BCD码,低位BCD数存入C中,高位BCD数存于B中,并将对应的ASCII码存入C1及B1中。分析:将1个字节中的两位BCD码分开,即分别取出其高4位和低4位。得到低位BCD码的方法是:屏蔽高4位、保存低4位。得到高位BCD码的方法是:逻辑右移4位,左边移入4个0。由未组合的BCD码转为ASCII码,只要加30H或“OR30H〞。DATASEGMENT;数据定义
ADB37H;被转换数
BDB?;安排结果保存空间
CDB?
B1DB?;保存中间结果
C1DB?;保存中间结果DATAENDS流程图及编码CODESEGMENTASSUMECS:CODE,DS:DATAMAINPROCFARSTART:PUSHDSMOVAX,0PUSHAX;保存返回地址
MOVAX,DATAMOVDS,AX;设置DS MOVAL,A;取出高位BDC码
MOVCL,4 SHRAL,CL MOVB,AL ORAL,30H;高4位,转换成ASCII码
MOVB1,AL;保存高4位的转换结果
MOVAL,A;取出低位BCD码
ANDAL,0FH MOVC,AL ORAL,30H;低位BCD码,转换成ASCII码
MOVC1,AL;保存低4位的转换结果 RET;返回DOSMAINENDPCODEENDS ENDSTARTP97:阅读下面程序,指出运行结果DATASEGMENTBLOCKDW0ABCDHBUFFDD?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATA
START:MOVAX,DATAMOVDS,AXMOVDX,BLOCKMOVAX,DXANDAX,0F0FHANDDX,0F0F0HMOVCL,4SHRDX,CLLEABX,BUFMOV[BX+0],ALMOV[BX+1],DLMOV[BX+2],AHMOV[BX+3],DHMOVAX,4C00HINT21HCODEENDSENDSTART4.3.3分支程序设计分支程序结构:跳转的实现在8088/8086指令系统中,判断的依据主要是运算结果及运算标志存放器中的状态位。实现跳转的指令是无条件跳转指令:JMPlabel与条件跳转指令:Jccshort-label双分支程序双分支程序有以下五个局部组成:⑴产生条件的语句:如算术运算指令、比较指令、移位指令等,通过它们影响标志存放器状态位ZF、CF、OF、SF等,为条件测试作准备。⑵条件测试语句:利用条件转移指令进行测试。⑶定向:根据判断的条件,决定程序的不同走向,在两种可能转移方向中选择其一。⑷顺序控制图:无论选择哪个方向,都必须保证执行分支段程序后,程序顺序执行下去。⑸标号:在分支程序段前设置标号,以便于转移。S1:…………;程序段1,产生条件
……JccBRANCH;条件测试,并定向
…………;分支程序段1……
JMPS2;顺序控制BRANCH:…………;分支程序段2……S2:……程序段1条件测试分支1分支2YNS2BRANCH图4.11双分支程序组成【例题4.4】比较两个无符号字节数,把大数存入MAX单元。CSEGSEGMENTASSUMECS:CSEG,DS:DSEGSTART:MOVAX,DSEG;给数据段地址附值MOVDS,AXMOVAL,NUMBER;取第一个数CMPAL,NUMBER+1;与第二个数JNCBRANCH;假设第一个数>第二个数,转BRANCHMOVAL,NUMBER+1;否那么,第二个数大BRANCH:MOVMAX,AL;保存较大数MOVAH,4CHINT21HCSEGENDSENDSTART;汇编结束DSEGSEGMENTNUMBERDB32h,54hMAXDB?DSEGENDS数据定义码段多分支程序设计多分支结构中,条件有多个。这些条件之间存在两种情况:一是所有条件中只可能有一个条件成立,称为“相异性条件〞;二是所有条件中可能有两个以上甚至所有条件都成立,称“相容性条件〞。对于相异性条件,要保证各个条件所对应的分支程序段互斥执行,即对特定的输入,只能选择分支程序中的一个运行。对于相容性条件,注意条件判定的次序,一旦找到成立的条件后,就执行相应的程序段,其后的条件是否成立,就不进行判断了。多分支程序设计方法
设计多分支程序的关键是如何按条件对多分支进行判断,从而根据不同的条件,转移到不同的入口去执行。常用方法有三种:转移表法地址表法逻辑分解法。⑴转移表法转移表法也称为跳转表法,其设计思想是:把转移到各分支的转移指令预先依次存放在一张表中,此表称为“跳转表〞,如图4.13所示;分支选择时,先计算实现该分支的跳转指令在跳转表中的地址x;然后通过一个JMPx指令,跳转到该处,实现分支选择,如图4.14所示。跳转表【例题4.5】设一监控程序,有10个编号分别为0~9控制命令键,如启动、执行、复位等,按下任一命令键相当于发出一条键盘命令,而这些命令功能的实现由10个子程序完成,这些子程序的入口地址为ADR0~ADR9。采用转移表法,首先将JMPADR0~JMPADR9的10条跳转到10个子程序的指令存于跳转表中。如果按键号为X,因每条跳转指令长度为3个字节,那么按键X对应的命令子程序的跳转命令在跳转表中的偏移量是3X。设X已送入存放器AL,由X实现转向相应命令子程序的程序如下:MOVAH,0MOVBL,ALADDAL,AL;求2XADDAL,BL;求3X,即位移量MOVBX,OFFSETBRA_TAB;设BRA_TAB为表首ADDBX,AXJMPBX⑵地址表法如果把上述跳转表中的跳转指令换成各分支程序的入口地址,即为地址表。地址表法指:多分支跳转时通过采用间接寻址方式,从地址表中找到分支入口地址实现分支选择。【例题4.6】某工厂有8种产品的加工程序R0~R7分别存放在以ADR0~ADR7为首地址的内存区域,这8个首地址连续存放在以BASE为首地址的地址表内,如下图。从图知:偏移量=产品编号×2表地址=表基地址+偏移量根据产品编号,选择加工程序的局部代码如下:DSEGSEGMENTBASEDWADR0,ADR1,ADR2,ADR3,ADR4,ADR5,ADR6,ADR7;地址表BNDW?;产品编号DSEGENDSCSEGSEGMENT
MOVSI,BN;取产品编号
ADDSI,SI;计算偏移量
MOVBX,BASE[SI];计算表地址
JMP[BX];分支跳转
RETSTARTENDPCSEGENDSENDBEGIN⑶逻辑分解法逻辑分解法的思路是将多分支结构按条件的先后依次分解成一串双分支结构,然后使用双分支的实现方法进行程序设计。此方法多用于相容性条件的多分支程序。【例题4.7】假设存放器AL中存放了当前外部中断请求的情况。AL中的每一位D7~D0对应一个中断源的中断请求,共8个INT7~INT0。假设有中断请求INTi,对应位Di为1;无中断请求,对应位为0,并设某一刻系统只能响应一个中断请求。由于系统中可能会同时出现多个中断请求(即AL中同时有多位为1),因此必须对中断请求设置优先级。假定优先级顺序与数据位低到高的顺序一致,即D0上中断请求最高,D7上中断请求最低,处理流程如下图。在进行条件测试时,通过对存放器AL移位,依次检测各位,程序为:……RORAL,1;取D0位JCR0;检测D0位RORAL,1;取D1位JCR1;检测D1位RORAL,1;取D2位JCR2;检测D2位……RORAL,1;取D7位JCR7;检测D7位……【例】编程实现以下函数的功能,其中X、Y为无符号字节数。〔多分支〕流程图(AL)=X(BL)=Y开始(AL)=(BL)?Z=0YZ=1Y(AL)>(BL)?NZ=-1N结束PUSH DSSUB AX,AXPUSH AXMOV AX,DATMOV DS,AXCMP AL,BLJE C1 JA C2EXT: MOVZ,AL RETMOV AL,X MOV BL,YC1:MOV AL,0JMP EXTC2:MOV AL,1JMP EXTMOVAL,-1CMPAL,BL JEC1 JAC2 MOVAL,-1 JMP EXTC2: MOV AL,1 JMP EXTC1:MOV AL,0EXT:MOVZ,AL RETMainendpCSEGENDSENDSTARTSk41.asmDATASEGMENTXDB56hYDB88HZDB?DATAENDSCSEGSEGMENTASSUMECS:CSEG,DS:DATAMainprocfarSTART: PUSH DS SUBAX,AX PUSH AX MOV AX,DATA MOV DS,AX MOV AL,X MOV BL,Y循环结构程序设计(1)初始化局部这是循环的准备局部,为程序操作、地址指针、循环计数、结束条件等设置初始值。(2)循环体,包括以下3个局部:循环工作局部这是循环程序的主体,完成程序的根本操作,循环多少次,这局部语句就执行多少次。循环修改局部修改循环工作局部的变量地址等,这保证每次重复时,参加执行的数据能发生有规律的变化。循环控制局部保证循环条件满足时进入循环;循环结束条件不满足时,退出循环,执行循环体外的后续语句。(3)循环结束局部完成循环结束后的处理,如数据分析、结果的存放等。循环程序典型结构零次或先判断后执行先判断循环条件是否满足。当循环条件满足时,执行循环体;当循环条件不满足时,执行结束局部。这种结构的循环,有可能循环体一次也得不到执行非零次或先执行后判断循环体至少执行一次后,才判别循环条件循环程序典型结构【例】(P100)统计BUFF缓冲区数据中负数的个数。
数据段定义如下:DATA SEGMENTBUFF DB-1,-3,5,6,9,… ;定义若干字节带符号数CUNT EQU $-BUF F ;计算数据块长度MEM DB ? ;定义存放结果单元DATA ENDS〔1〕先执行后判断DATASEGMENTBUFFDB-1,-3,5,6,9,0,78; 定义带符号数CUNTEQU$-BUFF;计算数据块长度MEMDB?;定义存放结果单元DATAENDSCSEGSEGMENTASSUMECS:CSEG,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVBX,OFFSETBUFF;建立数据指针
MOVCX,CUNT ;设置循环次数
MOVDL,0 ;结果初值
NEXT:MOVAL,[BX];取数据
ADDAL,0JNSPLUS;是正数,转去PLUSINCDL;是负数,负数个数+1PLUS:INCBX;调整数据指针
LOOPNEXT;CX-1≠0,继续循环
MOVMEM,DLMOVAH,4CHINT21HCSEGENDSENDSTART;汇编结束【例】P100AX存放器中有一个16位的二进制数,编程统计其中1的个数,结果存放在CX存放器中。控制循环体的条件是:当AX内容为全0,不必再继续统计。〔2〕先判断后执行循环体可能一次都不执行。关键程序如下:
MOVCX,16MOVDL,0 ;置结果计数器初值BB1: AND AX,AX ;AX=0否
JZ EXIT ;是,退出循环
SAL AX,1 ;否,AX的最高位移至CF中
JNC ZERO ;CF=0,转ZERO继续循环
INC DL ;CF=1,结果计数器加1ZERO:LOOP BB1 EXIT: 方法二:每位和1“与〞,不等0那么为1。 MOV CX,16 MOV DX,0001HAA: TEST AX,DX JZ LOP : ;Di=1LOP: SHR AX,1 LOOP AA方法三:LOP: TEST AX,0FFFFH JZ STOP JNS SHIFT ;查SF INC CXSHIFT:SHL AX,1 JMP LOP STOP:HLT3.循环控制方法每个循环程序必须选择一个循环控制条件,来控制循环的运行和结束。常用循环控制条件〔方法〕:〔1〕计数控制——循环次数,每循环一次加/减1。〔2〕条件控制——循环次数未知,须根据条件控制循环。〔3〕状态控制——根据事先设置或实时检测的状态来控制循环。*【例】统计字符串STRING中空格的个数。数据定义为:DSEGSEGMENTSTRINGDB‘Wherethereisawill,’
DB‘thereisaway.$’
RESULTDW?DSEGENDS被统计的字符串开设结果存放单元CSEGSEGMENTASSUMEDS:DSEG,CS:CSEGSTART:MOVAX,DATAMOVDS,AX给数据段段地址附值取数空格?累计计数器加1修改地址指针结束符?MOVBX,OFFSETSTRINGMOVDX,0NEXT:MOVAL,[BX]CMPAL,‘$’
JZFINCMPAL,20HJNZCONTINCDXCONT:INCBXJMPNEXTFIN:MOVRESULT,DXMOVAH,4CH
INT21HCSEGENDSENDSTART初始化保存结果结束YNYN循环程序控制方法之一:计数法〔循环次数〕1.正计数法2.负计数法计数器的初值为0,每执行一遍循环,计数器加1,然后与规定的循环次数比较,假设相等,那么结束循环,否那么继续循环。计数器的初值为循环次数,每执行一遍循环体后,计数器减1,当减为0时,结束循环,否那么继续循环。正计数法负计数法循环程序控制方法之二:条件控制
当只知道进入或结束循环的条件,而无法知道循环次数时,可采用条件控制法。1.精度:对于数值求解问题,有时无法得到精确解。通常的方法是,在迭代计算过程中,把本次迭代结果与前一次迭代结果相比,当符合精度要求时,结束迭代循环。2.设置结束标志:在数组和表格处理问题中,在数据表格末尾设置一结束标志,作为循环结束条件。【例】〔P101〕在BLOCK内存区中有一串字符,试编程统计“%〞之前的字符个数DATASEGMENTBLOCKDB‘ANDEPO%WR’COUNTEQU$-BLOCKMEMDB0DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVSI,OFFSETBLOCKMOVCX,COUNT
LOOP1:MOVAL,[SI]CMPAL,‘%’JZDONEINCBYTEPTRMEMINCSILOOPLOOP1DONE:MOVAX,4C00HINT21HCODEENDSENDSTART*逻辑尺【例4.10】设在数据组X和Y中各存在有10个数据元素。试编写程序计算:Z1=X1+Y1、Z2=X2+Y2、Z3=X3-Y3、Z4=X4-T4、Z5=X5-Y5Z6=X6+Y6、Z7=X7-Y7、Z8=X8-Y8、Z9=X9+Y9、Z10=X10+Y10并把结果存入数组Z中。
数据定义:DSEGSEGMENTXDWX1,X2,X3,X4,X5,X6,X7,X8,X9,X10YDWY1,Y2,Y3,Y4,Y5,Y6,Y7,Y8,Y9,Y10ZDW10DUP(?)LRDW0000000011011100BDSEGENDSX1+Y1X3-Y3逻辑尺采用子程序优点⑴简化了程序设计过程,使程序设计时间大量节省;⑵缩短程序的长度,节省计算机汇编源程序的时间和程序的存储单元;⑶增加程序的可读性,便于程序修改。4.3.5子程序设计调用图示…………CALLSUB1………………CALLSUB2……RET………………RET主程序子程序SUB1子程序SUB2主过程子过程1CALL
子过程1断点1子过程嵌套示意图子过程2①②③④⑤⑥④⑤RETRETCALL
子过程2断点2⑥⑦⑧⑨子程序中断在中断程序中又调用子程序子程序设计中的问题主程序与子程序的连接主、子程序都存放在代码段:CALL:断点保护,转子程序。RET:断点恢复。 假设主、子程序在同一代码段,为段内调用; 假设主、子程序各在不同的代码段,为段间调用。子程序设计1、过程定义、过程调用过程名PROC[类型]
…RET
…过程名ENDP〔1〕.定义〔2〕.调用CALL过程名NEAR子程序书写形式CODESEGMENTASSUME……
MAINPROCFAR
……
CALLSUB1
……
RET
SUB1PROCNEAR
……
CALLSUB2
……
RET
SUB2PROCNEAR
……
RET
SUB2ENDP
SUB1ENDP
MAINENDPCODEENDS
FAR子程序书写形式CODE1SEGMENTASSUME……
MAINPROCFAR
……
CALLSUB
……
RET
MAINENDPCODE1ENDSCODE2
SEGMENTASSUME……
SUBPROCFAR
……
RET
SUBENDPCODE2ENDSCALL指令段内调用直接寻址间接寻址CALLproc-nameCALLdisp16①IP←IP+偏移量
②IP入栈;例:CALLSUB1寻址方式格式操作注:段内调用,CS不变
CALLr16/m16①IP入栈;②IP←(r16)/(m16)例:CALLBXCALLWORDPTR[BX]CALL指令段间调用直接寻址间接寻址CALLFARproc-name①CS入栈;②IP入栈;③CS←过程的段地址;④IP←过程的偏移地址。
例:CALLfarSUB1寻址方式格式操作CALLfarmem32①CS入栈;②IP入栈;③IP←(EA+1,EA)④CS←(EA+3,EA+2)
例:CALLfar[BX]远过程名RET指令段内:RETRETexpIP出栈①IP出栈②SP←SP+exp
段间:RETRETexp①IP出栈②CS出栈
①IP出栈②CS出栈③SP←SP+exp
返回类型格式操作注:返回类型由调用类型定子程序参数传递方法一:存放器方法二:内存方法三:堆栈参数:入口参数出口参数在子程序中被处理的数据表示子程序处理结果的数据软延时:指利用CPU执行指令需要消耗一定时间的特点实施的延时,常用减1循环来实现。例:8088CPU,主频4.77M,每个时钟周期为:1/4.77M=0.21μs。循环指令LOOP,当CX不为零时,执行循环转移分支,占用17个时钟周期;当CX为零时,退出循环,占用5个时钟周期。如果CX初值是2801时,执行指令WAIT1:LOOPWAIT1,所需时间为:(0.21×2801)×17+0.21×5≈10ms
10ms延时子程序;子程序:DELAY;功能:实现软件延时,延时单位时间为10ms;入口参数:BX,延时常数,实际延时时间为:10*BX(ms);出口参数:无DELAYPROCNEAR
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- XX经济开发区标准化厂房建设工程可行性研究报告
- 兼职督导管理办法
- 内控支出管理办法
- 内部岗位管理办法
- 内部项目管理办法
- 军休经费管理办法
- 军队学籍管理办法
- 农地流转管理办法
- 农机仓储管理办法
- 农村磨坊管理办法
- 2024-2030年中国白糖行业市场运行状况及发展规模预测报告
- 法务岗位招聘笔试题与参考答案
- 安全专题课件教学课件
- 2024自制抱杆起重吊装方案的安全规定
- 成功食品库房规划方案
- 三年级下册口算题大全(可打印版)
- 生态养生养老综合示范区建设项目投资可研报告
- 四川省泸州市2024年七年级下学期数学期末考试试卷附答案
- JT-T 1495-2024 公路水运危险性较大工程专项施工方案编制审查规程
- 药物临床试验方案模板
- 《物流大数据分析》课程标准
评论
0/150
提交评论