第三章-汇编语言程序设计_第1页
第三章-汇编语言程序设计_第2页
第三章-汇编语言程序设计_第3页
第三章-汇编语言程序设计_第4页
第三章-汇编语言程序设计_第5页
已阅读5页,还剩83页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第三章-汇编语言程序设计第一页,共88页。3.1汇编语言的基本语法3.1.1汇编语言源程序结构

3.1.2汇编语言的语句格式3.1.3汇编语言的数据3.1.4表达式与运算符3-2第二页,共88页。3.1.1汇编语言源程序结构80X86/Pentium系列MPU汇编语言都是以逻辑段为基础,按段的概念来组织代码和数据的。因此,源程序结构与逻辑段的定义方法密切相关,而宏汇编语言MASM5.0以上的版本中,逻辑段既可用完整段定义,又可用简化段定义。3-3第三页,共88页。1.标准的单模块源程序框架[.586]

DATASEGMENT[USE16/USE32] ;定义数据段

;数据定义伪指令序列

DATAENDS

STACKSEGMENT[USE16/USE32]STACK ;定义堆栈段

;数据定义伪指令序列

STACKENDS

CODESEGMENT[USE16/USE32] ;定义代码段

ASSUMECS:CODE,SS:STACK,DS:DATA,ES:DATA

START:MOVAX,DATA ;取数据段基址

MOVDS,AX ;建立DS的可寻址性

MOVES,AX ;建立ES段的可寻址性

;核心程序段

MOVAH,4CH ;返回DOS操作系统

INT21H CODEENDS

ENDSTART⑴一个源程序由若干逻辑段组成。一般一个源程序具有数据段、附加数据段、堆栈段和代码段;但只有代码段是必不可少的。

⑵采用完整段定义时,对程序中定义的逻辑段,要说明逻辑段与段寄存器的寻址关系。ASSUMECS:CODE,SS:STACK,DS:DATA,ES:DATA⑶对数据段(有时还有堆栈段),程序中要包含初始化段寄存器的语句。MOVAX,DATAMOVDS,AXMOVES,AX程序中要包含返回DOS的语句。MOVAH,4CHINT21H⑸源程序(模块)以END伪指令结束

ENDSTART3.1.1汇编语言源程序结构3-4第四页,共88页。3.1.1汇编语言源程序结构(1)使用DOS的4CH号功能调用这种方法是在代码段结束前加调用语句:MOVAH,4CH;功能号4CH→AHINT21H;中断调用(2)使用20H号软功能调用调用方式是在代码段结束前加调用语句:INT20H(3)使用DOS的0号功能调用调用方式是在代码段结束前加调用语句:

MOVAH,0INT21H2.返回DOS状态的方法3-5第五页,共88页。(4)将主程序定义为远过程也称为“标准序”方法。这种方法是在代码段开始处按下述方式定义主程序:

CODE SEGMENT… ASSUME…主过程名 PROCFAR PUSHDS SUBAX,AX ;标准序

PUSHAX

RET主过程名ENDP

END主过程名3.1.1汇编语言源程序结构3-6第六页,共88页。3.1.2汇编语言的语句格式1.语句种类●指令语句是可执行语句,由硬件(CPU)完成其功能,汇编时产生目标代码。●伪指令语句

不可执行语句,其功能由相应软件完成,不产生目标代码。●宏指令语句

用户定义的新指令,汇编时产生相应的目标代码。

3-7第七页,共88页。3.1.2汇编语言的语句格式指令语句:[标号:]助记符[操作数][;注释]伪指令语句:[名字]定义符[操作数][;注释]●标号和名字——分别是给指令单元和伪指令起的符号名称,统称为标识符。(注意组成的语法规则)●助记符和定义符——分别用于规定指令语句的操作性质和伪指令语句的伪操作功能,统称操作符。2.语句格式3-8第八页,共88页。●操作数

3.1.2汇编语言的语句格式操作数允许有多个,这时各操作数之间要用逗号“,”隔开。伪指令语句中操作数的格式和含义则随伪操作命令不同而不同,有时是常量或数值表达式,有时是一般意义的符号

(如变量名、标号名、常数符号等),有时是具有特殊意义的符号(如指令助记符、寄存器名等)。

指令语句中的操作数提供该指令的操作对象,并说明要处理的数据存放在什么位置以及如何访问它,它可以是常量操作数、寄存器操作数、存储器操作数和表达式。3-9第九页,共88页。3.1.3汇编语言的数据

汇编语言中使用的数据有常数、变量和标号。

1.常数常数是指那些在汇编过程中已有确定数值的量,分为数值常数和字符串常数两类。主要用作:指令语句中的立即操作数基址、变址或基址加变址寻址中的位移量伪指令语句中用于给变量赋初值3-10第十页,共88页。3.1.3汇编语言的数据

标号是指令的符号化地址,一定在代码段,而变量是数据的符号化地址,一般在数据段,有时也可在代码段定义。●变量与标号有三个共同属性:段基址:所在段的起始地址(SEG)偏移值:相对于段基址的位移量(OFFSET)类型:所占字节数(TYPE)2.变量与标号3-11第十一页,共88页。3.1.3汇编语言的数据

(1)标号可以用作转移控制类指令的操作数,但变量不能。(2)变量可以用作基址、变址或基址加变址寻址的位移量,但标号不能。●变量与标号区别3-12第十二页,共88页。例3.1

假设VAR1和VAR2为字变量,LAB为程序中的一个标号,判断下列指令是否正确,若错误请指出错误之处:

①ADDVAR1,VAR2②SUBAL,VAR1③JNZVAR1④JMPLAB[SI]⑤JMPNEARLAB⑥MOVAX,VAR1[BX]⑦JMPVAR2[BX]3.1.3汇编语言的数据

错,不允许存储器变量间直接传数错,源与目的操作数类型不一致错,变量不能用作条件转移指令的操作数错,标号不能用作变址寻址的位移量错,缺PTR运算符正确正确3-13第十三页,共88页。3.1.4表达式与运算符表达式由运算符和运算对象组成。●算术运算符●逻辑运算符●关系运算符●汇编语言特定的运算符运算符●常数、变量和标号●操作数●构成程序的段和偏移量…运算对象3-14第十四页,共88页。

●数值表达式指在汇编过程中能够由汇编程序计算出数值的表达式。可作为指令中的立即操作数和数据区中的初值使用。例如:MOVBX,0FFF0HAND0B234HMOVAL,4CHEQ2MOVAH,4CHGT1MOVAX,SEGLABLE3.1.4表达式与运算符

表达式是汇编语句操作数的基本形式,分为数值表达式和地址表达式。3-15第十五页,共88页。3.1.4表达式与运算符●地址表达式其值表示存储器地址,一般都是段内的偏移地址。与变量一样,地址表达式也具有段值、偏移值和类型属性。地址表达式主要用来表示指令语句中的操作数,例如:MOVAX,BASE[EAX][EBX]JMPBASE[EAX]

LEABX,BASE+123-16第十六页,共88页。3.2.1方式选择伪指令3.2.2逻辑段定义伪指令3.2.3数据伪指令语句3.2.4模块定义伪指令3.2.5过程与宏定义伪指令3.2.6结构定义伪指令

3.2伪指令语句3-17第十七页,共88页。3.2.1方式选择伪指令方式选择伪指令用于通知汇编程序,当前的源程序指令是哪一种CPU指令,经过汇编链接之后生成的目标程序在哪一种CPU机型上运行。不属于选定CPU的指令均为非法指令。所以,方式选择伪指令本质上也就是指令集选择伪指令。通常,方式选择伪指令放在程序的头部,作为源程序的第一条语句。缺省时默认8086指令集。3-18第十八页,共88页。3.3.2逻辑段定义伪指令1.完整段定义伪指令80X86/Pentium系列微处理器汇编语言有两种逻辑段定义方法:完整段和简化段定义采用完整段定义伪指令可具体控制汇编程序(MASM)和链接程序(LINK)在内存中组织代码和数据的方式。主要包括段定义语句和段寄存器说明语句。

3-19第十九页,共88页。3.3.2逻辑段定义伪指令格式:段名SEGMENT[定位类型][,组合类型][,字长选择][,‘类别’]段体 ;由指令、伪指令和宏指令语句组成段名ENDS

⑴段定义语句

说明:

(1)SEGMENT/ENDS是一对段定义语句,一个逻辑段从SEGMENT语句开始,到ENDS语句结束。(2)段名是用户定义的段的标识符,用于指明段的基址。(3)4个可选参数用于为源程序的汇编、连接提供必要的信息,特别是模块化程序,各个模块如何定位,彼此之间如何连接,将较多地涉及到定位类型和组合类型的选择。指定段起点的边界类型:BYTE(字节)WORD(字)DWORD(双字)PARA(节)PAGE(页)

定位类型告诉链接程序本段与其它模块中同名段的组合连接关系:PUBLIC连接到同一个物理段中STACK连接到同一个物理堆栈段中,并给SS:ESP赋值COMMON产生一个覆盖段。MEMORYAT表达式

组合类型定义段中使用的偏移地址和寄存器的字长USE16──表示该段字长为16位USE32──表示该段字长为32位字长选择3-20第二十页,共88页。3.3.2逻辑段定义伪指令举例:模块2(从模块):DSEGSEGMENTCOMMONARRAY_BDW200DUP(?)DSEGENDSSSEGSEGMENTSTACKDW50DUP(?)SSEGENDSCSEGSEGMENTPUBLIC

CSEGENDS

END模块1(主模块):DSEGSEGMENTCOMMONARRAY_ADW100DUP(?)DSEGENDSSSEGSEGMENTSTACKDW50DUP(?)SSEGENDSCSEGSEGMENTPUBLICASSUMECS:CSEG,DS:DSEG,SS:SSEGSTART:MOVAX,DSEGMOVDS,AX

CSEGENDSENDSTARTCSEGDSEG(共400字节)模块2代码模块2数据SSEG(共200字节)模块1代码模块2堆栈模块1数据逻辑段组合示意图模块1堆栈3-21第二十一页,共88页。⑵段寄存器说明语句

格式:ASSUME段寄存器:段名[,段寄存器:段名,…]功能:说明源程序中定义的段由那个段寄存器去寻址。说明:

⑴CS只能用于包含有程序的段,反之含有程序的段也只能以CS作为段寄存器。SS也一样,只能与堆栈段对应。⑵CS所对应的段名必须在该语句之前有定义。⑶该语句是说明性语句。3.3.2逻辑段定义伪指令3-22第二十二页,共88页。简化段有利于实现汇编语言程序模块与Microsoft高级语言程序模块的连接,它可以由操作系统自动安排段序,自动保证名字定义的一致性。但是命令文件(.COM)的编程不能使用简化段定义。⑴段次序语句(DOSSEG)⑵内存模式语句(.MODEL)⑶段语句

简化段定义有三种语句:3.3.2逻辑段定义伪指令2.简化段定义伪指令

3-23第二十三页,共88页。

使用简化段定义的独立汇编语言源程序框架:

DOSSEG .MODELSMALL .STACK[长度] .DATA …;数据语句 .CODE启动标号:MOVAX,@DATA;或MOVAX,DGROUP MOVDS,AX …;可执行语句

MOVAH,4CH;返回DOS INT21H END启动标号段语句.CODE.DATA.STACK3.3.2逻辑段定义伪指令DOSSEG段次序语句:规定各逻辑段在内存的顺序按DOS段次序约定排列。

.MODELSMALL内存模式语句:用于指定数据和代码允许使用的长度。3-24第二十四页,共88页。3.2.3数据伪指令语句格式:赋值语句:符号名EQU表达式功能:都是用符号名代替表达式的值。但赋值语句定义的符号名不能重新定义,而等号语句允许。1.符号定义伪指令等号语句:符号名=表达式

3-25第二十五页,共88页。

例3.2赋值语句与等号语句举例。赋值语句:

XEQU50 YEQUX+10 COUNTEQU$-ARRY 等号语句:

CON=5 BASE=200H

BASE=BASE+10H ;重新定义BASE3.2.3数据伪指令语句3-26第二十六页,共88页。2.数据定义伪指令伪指令格式:DBDWDDDFDQDT数据项[,数据项,…,数据项][变量名]功能:是为数据项或项表分配存储空间,给它们赋初值,并用一个符号名(称为变量)与之相联系。8位(字节)16位(字)32位(双字)48位(长字)64位(四字)80位(十字节)

3.2.3数据伪指令语句3-27第二十七页,共88页。使用说明:⑴给变量赋初值可以是赋确定的值,也可以是赋不确定的值(用“?”表示),还可以是用DUP运算符建立的多次拷贝。

例3.3

使用80X86汇编语言的伪操作命令定义:

VALDB93DUP(5,2DUP(2DUP(1,2DUP(3)),4))

则在VAL存储区内前10个字节单元的数据是

解:由内向外逐层展开,分别相当于:①93DUP(5,2DUP(2DUP(1,3,3),4))②93DUP(5,2DUP(1,3,3,1,3,3,4))③93DUP(5,1,3,3,1,3,3,4,1,3,3,1,3,3,4)即表示重复93个数据序列:‘5,1,3,3,1,3,3,4,1,3,3,1,3,3,4’

3.2.3数据伪指令语句3-28第二十八页,共88页。

⑵使用SEG、OFFSET、TYPE、LENGTH和SIZE运算符求变量的各种属性时,特别要注意:

对LENGTH运算符,如果变量是用重复数据操作符DUP说明的,则返回外层DUP给定的值;如果没有DUP说明,则返回值总是1。

对SIZE运算符有:SIZE=TYPE×LENGTH使用说明:

3.2.3数据伪指令语句3-29第二十九页,共88页。

解:此题有两层DUP定义,但最外层DUP给定的值为100,所以:(BX)=数组ARRAY的偏移地址;(CX)=数组ARRAY的长度=100;(SI)=数组ARRAY的类型=2。

例3.4若数组ARRAY在数据段中已作如下定义:

ARRAYDW100DUP(123H,3DUP(?)),1234H

试指出下列指令执行后,有关寄存器的内容是多少?MOV BX,OFFSETARRAYMOV CX,LENGTHARRAYMOV SI,0ADD SI,TYPEARRAY

3.2.3数据伪指令语句3-30第三十页,共88页。⑶操作符“$”是取地址计数器的当前值,常用于表达式定义数组长度。

例3.5

已知:

ORG0100H ARYDW3,$+4,5,6 CNTEQU$-ARY DB7,8,CNT,9下列指令执行后,AX、BX寄存器的值为多少?

MOVAX,ARY+2MOVBX,ARY+100100H03H0101H00H0102H06H0103H01H0104H05H0105H00H0106H06H0107H00H0108H07H0109H08H010AH08H010BH09H解:画出数组ARY的内存分配图。(AX)=[ARY+2]=[0102H]=0106H(BX)=[ARY+10]=[010AH]=0908H

3.2.3数据伪指令语句使用说明:3-31第三十一页,共88页。

⑷使用DB、DW、DD定义串数据(用‘’定义的字符串)时,允许定义的串长度不同,字符的存放顺序也不相同:DB是从左至右顺序为每个字符分配一个字节单元;DW是从左至右顺序为每2个字符分配一个字单元,且前面的字符在高字节,串长度不能超过2;DD是从左至右顺序为每4个字符分配一个双字单元,也是按前面的字符在高字节顺序存放,串长度不能超过4。

3.2.3数据伪指令语句3-32第三十二页,共88页。

例3.6今需在变量名为STRING的数据区中顺次存放数据‘A’、‘B’、‘C’、‘D’、‘E’、‘F’、‘G’、‘H’,请写出分别用汇编命令DB、DW和DD实现的语句。解:用DB、DW和DD实现的语句分别为:

STRINGDB‘ABCDEFGH’ STRINGDW‘BA’,‘DC’,‘FE’,‘HG’ STRINGDD‘DCBA’,‘HGFE’

3.2.3数据伪指令语句3-33第三十三页,共88页。3.2.4模块定义伪指令模块定义伪指令包括模块开始和模块结束语句。

1.模块开始语句(NAME)

格式:NAME[模块名]

功能:指示源程序开始,并指出该源程序的模块名。2.模块结束语句(END)

格式:END[标号/过程名]

功能:模块结束语句表示源程序到此结束。3-34第三十四页,共88页。3.2.5过程与宏定义伪指令过程定义伪指令宏定义伪指令宏和过程的比较3-35第三十五页,共88页。格式:过程名PROC[属性]

… ;过程体 [RET] … RET

过程名ENDP

说明:②过程允许嵌套调用,还可以递归调用。③过程与逻辑段也可以相互嵌套,但决不允许过程与段交叉覆盖。过程又称为子程序。它是一段必须通过CALL指令调用才能执行的程序段,执行完后通过一条RET指令返回原调用处。过程需先定义才能调用。

①过程体中必须至少包含一条RET指令,这是过程的出口。但也允许过程有多条RET指令,即过程有多个出口。1.过程定义伪指令3.2.5过程与宏定义伪指令

3-36第三十六页,共88页。宏定义格式:宏名MACRO[形式参数表]

;宏体 ENDM

说明:宏定义的宏名必须唯一,称为宏指令。宏指令一经定义就可以在源程序的任何地方调用。相当于由用户给汇编程序提供了一个新的操作码。

宏调用格式:宏名[实际参数表]3.2.5过程与宏定义伪指令

宏的概念与过程很相似,也是用一个宏名字来代替源程序中经常要用到的一个程序模块。2.宏定义伪指令

3-37第三十七页,共88页。3.2.5过程与宏定义伪指令

使用宏定义和宏调用时要注意两个问题:对带参数的宏指令,宏调用时实际参数与形式参数的类型要一致,以免产生无效调用。宏调用是用宏体中定义的指令序列替换宏指令,所以宏体内的标号要用LOCAL伪指令说明为局部标号,以免多次调用宏时,发生标号重复定义错误。LOCAL伪指令格式:

LOCAL标号1[,标号2,…]3-38第三十八页,共88页。解:宏定义如下:

MOVEMACROSARY,DARY

LOCALLP MOVSI,0 MOVCX,100LP:MOVAL,SARY[SI] MOVDARY[SI],AL INCSI LOOPLP ENDM例3.7

定义宏MOVE,其功能是将一个有100个字节元素的数组搬移到另一个数据区。进行宏调用:MOVEFIRST,SECOND宏展开如下:

MOVSI,0MOVCX,100??0000:MOVAL,FIRST[SI] MOVSECOND[SI],AL INCSI LOOP??00003.2.5过程与宏定义伪指令

3-39第三十九页,共88页。3.宏和过程的比较

宏和过程都可简化源程序的书写,因而也减少了程序出错的可能性。但两者使用上也有区别:3.2.5过程与宏定义伪指令

(1)宏操作可以直接传递和接收参数,而过程不能直接带参数。当过程之间需要传递参数时,必须通过堆栈、寄存器或存储器来进行,编程比宏要复杂。所以,宏汇编适合于代码较短,传送参数较多的子功能段使用,子程序适合于代码较长,调用比较频繁的子功能段使用。(3)引入宏操作并不会在执行目标代码时增加额外的时间开销,但过程调用由于要保护和恢复现场及断点,因此会延长目标程序的执行时间。(2)子程序不管被调用多少次它都只被汇编一次,即有唯一的一段目标代码;而宏指令则调用多少次就汇编多少次,每次调用都要在程序中展开并保留宏体中的每一行。3-40第四十页,共88页。3.2.6结构定义伪指令

在一些应用中,常需要将一些不同类型的数据组合成一个有机整体。这时就要用到汇编语言的结构化数据——结构。

与前述的字节、字类型数据不同,一个结构必须先经定义后才可以说明属于这种结构类型的变量,这是因为结构的组成是千变万化的。所以围绕结构定义,有两种伪指令语句:2.结构变量说明与赋初值语句

1.结构类型说明语句(STRUC/ENDS)3-41第四十一页,共88页。3.2.6结构定义伪指令

语句格式:结构名STRUC…;结构体,由数据定义语句构成结构名ENDSDATESTRUCMONTHDB?DAYDB?YEARDW?DATEENDS结构DATE的存储形式MONTH(1字节)DAY(1字节)YEAR(2字节)结构的定义明确地描述了该结构的组织形式,它告诉汇编程序属于这种组织形式的变量使用内存的模式。例如:

1.结构类型说明语句(STRUC/ENDS)3-42第四十二页,共88页。语句格式:

[变量名]结构名〈[域值表]〉例如:VARDATE<4,3,2004H>结构变量VAR的存储形式MONTH(1字节)DAY(1字节)YEAR(2字节)04H03H04H20HVAR3.结构的引用有两种方法:结构变量名.域名[基址或变址寄存器].域名MOVAX,VAR.YEARMOVCL,VAR.DAY上述引用也可用如下方法:MOVBX,OFFSETVAR

MOVAX,[BX].YEARMOVCL,[BX].DAY3.2.6结构定义伪指令2.结构变量说明与赋初值语句3-43第四十三页,共88页。3.3汇编语言程序设计入门3.3.1汇编语言程序的开发过程3.3.2基本结构程序设计3.3.3子程序设计与调用技术3.3.4DOS/BIOS功能调用3-44第四十四页,共88页。3.3.1汇编语言程序的开发过程与其它程序设计语言一样,汇编语言程序的开发过程可归结为:就需求分析、模块划分和算法确定等工作而言,各种程序设计语言是类似的,均可按软件工程的方法进行,但编程和调试则因程序设计语言而异。

需求分析根据需求和规模等因素划分模块确定各功能模块的求解算法、并定义所需的数据结构进行编程和调试3-45第四十五页,共88页。对汇编语言而言,根据数据结构和算法进行编码到形成可用程序的过程如下:

需求分析、数据结构和算法汇编语言源程序文件*.ASM目标代码程序文件*.OBJ可执行程序文件*.EXE可用程序连接编辑汇编调试3.3.1汇编语言程序的开发过程3-46第四十六页,共88页。3.3.2基本结构程序设计程序的基本结构形式有三种:●顺序结构●分支结构●循环结构理论上,三种基本结构是完备的,即任何功能的程序都可由顺序、分支和循环三种结构实现。3-47第四十七页,共88页。1.顺序程序设计●在实际应用中,纯粹用顺序结构编写的完整程序很少见,但是在程序段中它却是大量的存在。所以掌握它是编写复杂应用程序的基础。——顺序程序又称直线程序。●其特点是顺序执行的,无分支,无循环,也无转移,只作直线运行。3.3.2基本结构程序设计3-48第四十八页,共88页。2.分支程序设计在许多实际问题中,往往需要根据不同的情况和给定的条件做出不同的处理。要设计这样的程序,必须事先把各种可能出现的情况及处理方法都编写在程序中,以后计算机运行程序时,可自动根据运行的结果做出判断,有条件地选择执行不同的程序段,按这种要求编写的程序称为分支程序。3.3.2基本结构程序设计3-49第四十九页,共88页。分支1条件结束开始YN分支2(b)完全分支结构分支程序条件结束开始YN(a)不完全分支结构分支1结束开始条件ii=1i=n分支2分支n…i=2(c)多分支结构分支程序的结构有三种形式:

IF条件

THEN分支程序IF条件

THEN分支1

ELSE分支23.3.2基本结构程序设计3-50第五十页,共88页。⑴利用比较与条件转移指令实现分支

根据X(-128≤X≤127)的值求出Y。例3.9变量X的符号函数定义如下:Y=1X>00X=0-1X<0程序如下:

DATA SEGMENT X DB0F8H Y DB? DATA ENDS3.3.2基本结构程序设计3-51第五十一页,共88页。

CODE SEGMENT ASSUMECS:CODE,DS:DATASTART:MOV AX,DATA MOV DS,AX MOV AL,X ;取变量X的值

CMP AL,0 ;X与0比较

JG BIGR

JE FINISH ;X=0,Y=0 MOV AL,0FFH ;X<0,Y=-1

JMP FINISH BIGR:MOV AL,1 ;X>0,Y=1FINISH:MOV Y,AL ;保存函数值Y MOV AH,4CH INT 21H CODE ENDS END START3.3.2基本结构程序设计3-52第五十二页,共88页。⑵利用跳转表实现分支

——适于多分支结构。有三种跳转表:

BASE

关键字0ADR0

M

(c)根据关键字分支关键字nADRn关键字1ADR1+3+3nBASEJMP

JMPM

(b)根据表内指令分支JMP+3n+3BASEADR0

M

(b)根据表内地址分支ADRnADR1+2n+23.3.2基本结构程序设计3-53第五十三页,共88页。使用跳转表实现分支时,要特别注意表内地址分支和表内指令分支两种结构跳转表的定义方法和正确的寻址方式。表内地址分支在数据段定义跳转表,用存储器间接寻址;表内指令分支在代码段定义跳转表,用寄存器间接寻址。3.3.2基本结构程序设计3-54第五十四页,共88页。解:这是一个多分支结构程序,适合于用跳转表实现。假设用表内地址分支实现,此时,跳转表在数据段定义,转移要用存储器间接寻址的跳转指令。程序如下:

例3.10设某控制程序可完成8种产品的加工,每种加工程序对应一个数字(1~8)。现要求根据输入的值去加工相应产品。假设8种加工程序段与主程序在同一代码段中。3.3.2基本结构程序设计3-55第五十五页,共88页。例3.10表内地址分支程序

.486DATASEGMENT‘DATA’DISPDB‘Errorrepeatinput’DB0AH,0DH,‘$’

BASEDDSBR1,SBR2,SBR3,SBR4

DDSBR5,SBR6,SBR7,SBR8DATAENDSCODESEGMENT‘CODE’ASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXINPUT:MOVAH,1;输入数字序号INT21HCMPAL,‘1’

JBERR

CMPAL,‘8’

JAERR

SUBAL,‘1’ANDEAX,0000000FH

JMPBASE[EAX*4]SBR1:…SBR2:…

SBR8:…

ERR:CMPAL,‘E’JZEXIT

MOVDX,OFFSETDISPMOVAH,09H

INT21HJMPINPUTEXIT:MOVAH,4CHINT21HCODEENDSENDSTART此题也可用表内指令分支实现。这时,跳转表要在代码段定义,转移则要用寄存器间接寻址的跳转指令。程序如下:3.3.2基本结构程序设计3-56第五十六页,共88页。

.486DATASEGMENTUSE16‘DATA’DISPDB‘Errorrepeatinput’DB0AH,0DH,‘$’DATAENDSCODESEGMENTUSE16‘CODE’ASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXINPUT:MOVAH,1;输入数字序号INT21HCMPAL,‘1’

JBERR

CMPAL,‘8’

JAERR

SUBAL,‘1’

ANDAX,000FHMOVBX,AXSHLBX,1ADDAX,BX

MOVBX,OFFSETBASEADDBX,AXJMPBXBASE:JMPSUB1;跳转表

JMPSUB2JMPSUB8SUB1:…SUB2:…

SUB8:…ERR:CMPAL,‘E’JZEXIT;按E键结束

MOVDX,OFFSETDISPMOVAH,09H;显示提示信息

INT21HJMPINPUT;转重输入字符EXIT:MOVAH,4CHINT21HCODEENDSENDSTART例3.10表内指令分支程序3.3.2基本结构程序设计3-57第五十七页,共88页。3.循环程序设计●初始化部分●循环体

●循环修改●循环控制

凡要重复执行的程序段都可按循环结构设计。采用循环结构,可简化程序书写形式,缩短程序长度,减少占用的内存空间。※循环结构的程序一般包括下面几个部分:

3.3.2基本结构程序设计3-58第五十八页,共88页。※循环程序的两种组织方式(a)DO―WHILE结构循环修改条件结束开始YN循环初始化循环体(b)DO―UNTIL结构循环修改条件结束开始YN循环初始化循环体3.3.2基本结构程序设计3-59第五十九页,共88页。●计数控制●条件控制

●状态控制●逻辑尺控制※循环结束的控制方式:

3.3.2基本结构程序设计3-60第六十页,共88页。

(1)计数控制循环程序设计循环次数已知时用计数控制循环,这时常用CX作循环计数器,用循环指令LOOP控制循环。也可用其他通用寄存器作循环计数器,用DEC和JNZ指令控制循环。例3.11某存储区中存放着80名同学某科目的成绩(0~99分),假定此成绩以压缩BCD码形式存放。要求统计及格(60分以上)和不及格人数,统计结果仍以压缩BCD码形式存放。

解:此题循环次数已知,下面用CX作循环计数器,使用LOOP指令控制循环。BCD计数器加1用宏指令实现,程序如下:3.3.2基本结构程序设计3-61第六十一页,共88页。例3.11程序;定义宏,BCD加1计数BCD_ADD_1MACROADDR

MOVAL,ADDRADDAL,1

DAAMOVADDR,AL

ENDMDATASEGMENTBLOCKDB87H,60H,57H,…,90HCNTEQU$-BLOCKNUM1DB0;定义计数器NUM2DB0DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVSI,OFFSETBLOCKMOVCX,CNTAGAIN:MOVAL,[SI]

CMPAL,60H;比较

JNCNEXT

BCD_ADD_1NUM2

JMPNEXT1NEXT:BCD_ADD_1NUM1NEXT1:INCSI;修改指针

LOOPAGAINMOVAH,4CHINT21HCODEENDSENDSTART3.3.2基本结构程序设计3-62第六十二页,共88页。

例3.12

编写程序,将ASCII码表示的5位十进制数(≤65535)转换成16位二进制数,并存储起来。

解:设X=Xn-1…X1X0为十进制数,则X转换为二进制数的一般方法为:

X=Xn-110n-1+…+X110+X0该式可用计数循环结构从低位到高位依次对每位十进制数进行转换处理,求出每位十进制数对应的二进制数(Xi×10i),并累加求和。

假定用变量MULTIPLE保存第i位十进制数Xi对应的权值10i,变量BINAY保存转换的二进制数,ASCII码数的存放顺序是高位在前、低位在后。程序如下:3.3.2基本结构程序设计3-63第六十三页,共88页。例3.12程序DSEGSEGMENTASCDECDB‘23333’BINAYDW0MULTIPLEDW1DSEGENDSCSEGSEGMENTASSUMECS:CSEG,DS:DSEGSTART:MOVAX,DSEGMOVDS,AXMOVCX,10

;SI指向ASCII码数首址LEASI,ASCDEC DECSI

;BX指向ASCII码数个位MOVBX,5NEXT:MOVAL,[BX+SI]ANDAX,0FH

;计算当前十进制位对应的二进制数

MULMULTIPLE

ADDBINAY,AX;累加求和MOVAX,MULTIPLE

;计算下一十进制位对应的权值

MULCX MOVMULTIPLE,AXDECBXJNZNEXT;未完继续MOVAH,4CHINT21HCSEGENDSENDSTART3.3.2基本结构程序设计3-64第六十四页,共88页。当循环次数未知时,就要用条件或状态信号来控制循环。用条件控制时,常用比较指令CMP与条件转移指令Jcc结合控制循环结束.用状态控制时,状态信号既可由外设提供,也可由其他任务或过程提供,这时常用测试指令TEST与条件转移指令Jcc结合控制循环结束。⑵条件/状态控制循环程序设计3.3.2基本结构程序设计3-65第六十五页,共88页。例3.13

编程统计AX寄存器中1的个数。

解:要统计AX中1的个数,一个比较简单直观的办法是用移位的办法把各数位逐次移到最高位去,然后根据最高有效位是否为1来计数;循环结束采用计数值16来控制。但考虑到AX的值或者某次移位后AX的值可能为0的情况,为了缩短程序的执行时间,下面采用测试AX的值是否为0来作为循环结束的控制条件。程序如下:3.3.2基本结构程序设计3-66第六十六页,共88页。CODESEGMENT ASSUMECS:CODESATRT:MOVCX,0 ;统计计数器清0AGAIN:CMPAX,0 ;(AX)=0?

JZEXIT ;为0,结束

JNSNEXTINCCX ;AX最高位为1,统计NEXT:SHLAX,1 ;AX左移1位

JMPSHORTAGAINEXIT:MOVAH,4CHINT21HCODEENDSENDSTART例3.13程序此例说明算法和控制条件的选择对程序的工作效率有很大影响,而循环控制条件的选择又是很灵活的,应该根据具体情况来确定。3.3.2基本结构程序设计3-67第六十七页,共88页。

例3.14

从FIRST开始的100个单元中存放着一个字符串,结束符为$。编写一个程序,统计该字符串中字母‘A’的个数。

解:此例并不知道字符串的具体长度,所以不能直接使用计数循环。这时可用字符串结束标志(结束符‘$’)来控制扫描或比较结束。当然,经过适当处理,此例也可用计数循环控制。

下面给出这两种控制方法的程序。3.3.2基本结构程序设计3-68第六十八页,共88页。例3.14条件控制程序DATA SEGMENT

;定义字符串,结束符为$

FIRSTDB‘AGHJK…$’

NUMBERDB?DATA ENDS

CODESEGMENT ASSUMECS:CODE,DS:DATASTART:MOVAX,DATA MOVDS,AX

MOVBL,0

LEADI,FIRST;取串首址NEXT:MOVAL,[DI];取一个字符

INCDI

CMPAL,‘$’;与‘$’比较

JEEXIT;等于,结束

CMPAL,‘A’;与‘A’比较

JNENEXT;不等于,不统计

INCBL;找到,计数

JMPNEXT;继续EXIT:MOVNUMBER,BL

MOVAH,4CH INT21HCODEENDSENDSTART3.3.2基本结构程序设计3-69第六十九页,共88页。例3.14计数控制程序DATASEGMENTFIRSTDB‘AGHJK…$’

COUNTEQU$-FIRST

NUMBERDB?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATA MOVDS,AX ;DS、ES指向同一数据段MOVES,AX

MOVBL,0

LEADI,FIRST

MOVCX,COUNT

MOVAL,‘A’

CLDNEXT:REPNESCASB;找字符‘A’JNZEXIT;未找到,结束

INCBL;找到,计数

JMPNEXT;继续EXIT:MOVNUMBER,BL

MOVAH,4CH INT21HCODEENDS ENDSTART

3.3.2基本结构程序设计3-70第七十页,共88页。3.3.2基本结构程序设计(3)逻辑尺循环程序设计

——循环不规则时使用的一种循环控制方法

例3.15设有数组:X=[x1,x2,…,x10],Y=[y1,y2,…,y10]。试编制程序,计算:

z1=x1+y1 z6=x6+y6 z2=x2+y2 z7=x7-y7 z3=x3-y3 z8=x8-y8 z4=x4-y4 z9=x9+y9 z5=x5-y5 z10=x10+y10其中,xi,yi,zi(i=1,2,…,10)均为16位补码数。

定义一个二进制位序列——称为逻辑尺

1100010011每个数组元素zi对应一位,该位为1,表示计算zi时对应数组元素相加,否则相减。3-71第七十一页,共88页。例3.15程序3.3.2基本结构程序设计

DATA SEGMENTXDW x1,x2,x3,x4,x5DWx6,x7,x8,x9,x10YDW y1,y2,y3,y4,y5DWy6,y7,y8,y9,y10ZDW 10DUP(?)

SOCBEHDW11000BDATA ENDS

STACK SEGMENTSTACKSTNDB100DUP(?)STACK ENDSCODESEGMENTASSUMECS:CODE,SS:STACK,DS:DATASTART:MOVAX,DATA MOVDS,AX MOVBX,SOCBEH;取逻辑尺

MOVCX,10;置循环次数

MOVSI,0AGAIN:MOVAX,X[SI] ;取xi

SHLBX,1

JNCL1 ADDAX,Y[SI] ;求和

JMPL2L1: SUBAX,Y[SI] ;相减

L2:MOVZ[SI],AX ;保存zi ADDSI,2

LOOPAGAINEXIT:MOVAH,4CH INT21HCODEENDS ENDSTART3-72第七十二页,共88页。3.3.3子程序设计与调用技术同一个程序中,往往有许多地方都需要执行同样的一项任务(一段程序),而该任务又并非规则情况,不能用循环程序来实现,这时可以对这项任务独立地进行编写,形成一个子程序或过程。3-73第七十三页,共88页。CALLRET子程序语句序列2结束开始语句序列1子程序调用恢复现场返回开始保护现场语句序列子程序结构如图所示:3.3.3子程序设计与调用技术从子程序返回主程序则简称为“返主”通常将主程序向子程序转移叫子程序调用或过程调用,简称“转子”3-74第七十四页,共88页。设计或编写子程序时,着重要考虑两个问题:3.3.3子程序设计与调用技术●主程序与子程序的接口●主程序与子程序间的参数传递3-75第七十五页,共88页。●正确使用CALL/RET指令

●转子和返主过程中的现场保护和恢复

⑴主程序与子程序所使用的存储单元和寄存器尽量分开,互不干扰。这又有两种方法:3.3.3子程序设计与调用技术⒈主程序与子程序的接口3-76第七十六页,共88页。⑵将“现场”通过堆栈保存和恢复。SUBRPROCPUSHAXPUSHBX… ;子程序体POPBXPOPAX

RETSUBRENDP子程序这时,既可在子程序中保存和恢复,又可在主程序中保存和恢复。例如:…PUSHAXPUSHBXCALLSUBRPOPBXPOPAX…

主程序3.3.3子程序设计与调用技术3-77第七十七页,共88页。主程序在调用子程序时,往往要向子程序传递一些参数;同样,子程序运行后也经常要把一些结果传回给主程序。主程序与子程序之间的这种信息传递称为参数传递。一般将子程序需要从主程序获取的参数称为入口参数,而将子程序返回给主程序的参数称为出口参数。入口参数使子程序可以对不同数据进行相同功能的处理,出口参数使子程序可送出不同的结果至主程序。3.3.3子程序设计与调用技术⒉主程序与子程序的参数传递

3-78第七十八页,共88页。常用的参数传递方法有:

寄存器传递法

存储器传递法

堆栈传递法

具体采用何种方法要根据情况事先约定好,有时可能同时采用多种方法。

3.3.3子程序设计与调用技术3-79第七十九页,共88页。(1)利用寄存器传递参数调用前,主程序将参数保存在某些通用寄存器中,子程序则直接引用寄存器中的参数。出口参数也可通过寄存器返回给主程序。这种方法简单快捷,但需占用通用寄存器,只适合参数较少的场合。

例3.16用子程序调用计算:X3+Y3。用子程序计算:X3入口参数:AL出口参数:EAX3.3.3子程序设计与调用技术3-80第八十页,共88页。

.486DATASEGMENTXDB68HYDB0E6HRESULTDD?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AX

MOVAL,X

CALLCUBICAL;计算X3MOVEBX,EAX

MOVAL,Y

CALLCUBICAL;计算Y3ADDEAX,EBXMOVRESULT,EAXMOVAH,4CHINT21HCUBICALPROCPUSHBX

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论