微机原理-汇编语言程序设计_第1页
微机原理-汇编语言程序设计_第2页
微机原理-汇编语言程序设计_第3页
微机原理-汇编语言程序设计_第4页
微机原理-汇编语言程序设计_第5页
已阅读5页,还剩265页未读 继续免费阅读

下载本文档

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

文档简介

微机原理--汇编语言程序设计第一页,共270页。6.1汇编语言语法6.1.1计算机程序设计语言的演变1.机器语言(MachineLanguage)

任何计算机实际上只能直接识别设计微处理器时所规定好的,一整套用“0”、“1”数字代码表示的机器指令。这些机器指令的全体是指令系统。不同类型的CPU,其机器语言必然是不同的。这种直接用机器指令来编制计算机程序的方法就称为机器语言程序设计。教学用的单板计算机一般都直接采用机器语言编程。这种直接用机器语言编程的方法难度大,阅读、查错和修改程序也很不方便。通常,只有当编程者对CPU指令系统比较熟悉,编写的程序较短时,才有可能直接用机器语言来写。人们为了摆脱编程中这种原始而低级的状态,就设法采用一组字母、数字或字符来代替机器指令,这样就产生了汇编语言的概念和方法。第二页,共270页。2.汇编语言(AssemblyLanguage)和机器语言相比,使用汇编语言来编写程序可以用助记符来表示指令的操作码和操作数,也可以用标号和符号来代替地址、常量和变量。但由于不同CPU的指令系统的指令编码不同,因此与之相应的汇编语言亦不相同。由于这种符号化的语言使用了用英文字母缩写表示的助记符,便于识别与记忆。另外,汇编程序还引入了新的汇编指令——伪指令和宏指令,使得采用汇编语言进行程序设计更为方便灵活。第三页,共270页。图6.1汇编程序的“翻译”作用第四页,共270页。3.高级语言(Highlevellanguage)低级语言编程方式阻碍了计算机在国民经济及日常生活中的推广应用。随着计算机科学的发展,软件、硬件技术在相辅相成、相互支持中不断改进与完善,逐步创造出许多适用于不同应用场合的计算机高级语言,如BASIC、FORTRAN、COBOL、PASCAL、FORTH、C语言等。这些高级的程序设计语言,使用了更接近于人们的自然语言(英语)和习惯的教学语言来描述算法的执行过程,从而使编写的程序更加直观和简练。这些高级语言通常都包含有各种函数计算、字符串处理、数据I/O等功能。所以程序的编写、阅读和修改变得相当容易掌握和使用。第五页,共270页。高级语言无论是面向问题或面向过程,一般总是独立于具体机器的。程序员可不必了解机器的指令系统和内部的具体结构,而把精力集中在正确掌握语言的语法规则和算法的程序实现上。同样,高级语言也必须借助于更强有力的翻译系统——编译程序(Compiler)才能将源程序转换成相应的机器语言目标程序。与汇编程序不同,此处一条最简单的高级语言语句,可能对应着一组机器指令。第六页,共270页。6.1.2为什么要用汇编语言编写程序为什么还要学习和使用汇编语言呢?主要有以下几点:(1)汇编语言非常接近机器语言程序,通过编制汇编语言程序,可以更清楚地了解计算机的工作过程。(2)现在的微机系统中,底层的一些功能仍然靠汇编语言程序来实现。(3)汇编语言程序的效率通常高于高级语言程序。第七页,共270页。6.1.3汇编语言的语句种类及其格式1.指令语句每一条指令语句在汇编时都要产生一个可供机器执行的机器目标代码,所以这种语句又叫可执行语句。指令语句的格式如下:标号:(前缀指令)助记符(操作符);(注释)(1)标号。这是一个任选字段。标号是指令语句的标识符,在语句之首,必须以“:”作为结束符。第八页,共270页。标号的组成规则如下:①必须由字母、数字(0,…,9)及特殊符号(?,·,@,-,$)组成,且必须以字母打头。②字符总数限制在31个以内。③不能使用属于系统专用保留字(Reservedword)。保留字主要有CPU中各寄存器名(如AX,CS);指令助记符(如MOV,ADD);伪指令(SEGMENT,DB);表达式中的运算符(如GE,EQ)和属性操作符(如PTR,OFFSET,SEG等)。语句格式中带()的项,是可有可无的项。如果有此项时,书写时不能加()括号。在有些指令语句中,需要在助记符前加前缀指令(例如LOCK或REP),中间应用空格使两者分开,如REPMOVSB。第九页,共270页。(2)指令助记符。这是为指令操作码规定的符号。任何指令语句都需要此部分,它表示了指令语句的基本操作功能。如MOV是传送指令的助记符,ADD是加法指令的助记符。(3)操作数。操作数可以根据指令的功能需要,可不带操作数,带1个操作数或2个操作数,若有两个操作数时,中间用“,”号分开。例如,NOP;STD;INCSI;ADDBL,30H。而操作数与助记符之间必须以空格分隔。(4)注释。注释是为方便程序人员阅读程序而加的说明。它既不影响源程序的汇编,也不会出现在目标程序中。通常并不要求每个汇编语句都应加注释。第十页,共270页。6.1.4常数、标号、变量及表达式1.常数常数就是指令中出现的那些固定值,可以分为数值常数和字符串常数两类。例如,立即数寻址时所用的立即数,直接寻址时所用的地址,ASCII字符等都是常数。常数除了自身的值以外,没有其它属性的数值。在源程序中,数值常数按其基数的不同,可有二进制数、八进制数、十进制数、十六进制数等几种不同的表示形式。汇编语句中用不同的后缀加以区别。①二进制数:数字后面跟字母B。如:00101101B第十一页,共270页。②八进制数:用数字0~7表示,数字后跟字母Q或字母O。例如:177567Q(或177567O)263Q(或263O)③十进制数:数字后跟字母D或不跟字母。例如:17893D(或17893)。④十六进制数:十六进制数用0~9及A~F表示。后面跟字母H。如:B7H,2031H。还应指出,汇编语句中的数值常数的第一位必须是数字,否则汇编时将被看成是标识符。如常数B7H在语句中应写成0B7H,FFH应写成0FFH。第十二页,共270页。字符串常数是由单引号‘’括起来的一串字符。例如:‘ABCDEFG’和‘179’。单引号内的字符在汇编时都以ASCII的代码形式存放在存储单元中。如上述两字符串其ASCII代码分别为41H、42H、43H、44H,…,4BH和31H、37H、39H。字符串最长允许有255个字符。第十三页,共270页。2.标号标号是用符号表示的地址,称为符号地址,用以指示此指令语句所在的地址。标号有3个属性:段地址、偏移地址和类型。标号的段地址和偏移地址属性是指标号对应的指令首字节所在的段地址和段内的偏移地址。标号的类型属性有两种:NEAR和FAR类型。标号如定义成NEAR类型,表示标号仅在本段内被引用;如定义成FAR类型,表示标号可以在段间使用。在转移和调用指令中常将标号作为转移目标地址使用。第十四页,共270页。3.变量变量是与一个数据项的第一字节相对应的标识符,它表示该数据项第一字节在现行段中的偏移量。变量的值在程序运行期间可随时修改。变量具有3个属性: ①段地址(SEG):变量所在段的段地址; ②偏移地址(OFFSET):变量所在段内的偏移地址; ③类型(TYPE):变量的类型是所定义的每个变量所占据的字节数。第十五页,共270页。在汇编语言中,变量是通过伪指令来定义的,其格式如下:变量名DB表达式;定义字节变量。变量名DW表达式;定义字变量。变量名DD表达式;定义双字变量。变量名DQ表达式;定义长字变量。变量名DT表达式;定义一个十字节变量。第十六页,共270页。上述伪指令的格式中的表达式可以有以下几种情况:(1)一个或多个常数或某个运算公式(其值应为常数)。当为多个常数或运算式时,其间用逗号隔开。在这种情况下,DB将给定常数定义为字节。DW将给定常数定义为字(两个字节),并给它分配两个存储单元,低位字节数占低地址单元,高位字节数占高地址单元。DD将给定常数定义为双字,分配4个存储单元。同理,DQ则分配8个存储单元,DT分配10个存储单元。当定义的变量有几个操作数时,则应从左到右由低地址向高地址顺序排列所定义的常数。第十七页,共270页。(2)带引号的字符串。字符串必须用单引号括住,字符串的字符不超过255个。DB对每一个字符分配一个存储单元,字符是由左向右按地址递增的顺序排列。例如KFDB‘ABC’;按41H、42H、43H的顺序由低地址到高地址分配存储地址。当操作数有多个字符串时,也是从左到右按地址递增顺序分配各字符串的存放单元。第十八页,共270页。(3)用问号作为表达式。不带引号的问号是一个保留字,它可用作数据类型伪指令DB、DW、DD语句中的表达式。用它告诉汇编程序,留出DB、DW、DD所分配的存储单元,原先内存内容不改变。例如:SURDW?;预留一个字(二个字节)。SUMDB?;预留一个字节。第十九页,共270页。(4)带DUP(重复方式)表达式。DUP是表达式中的一个操作符。此时表达式的格式为重复次数DUP(表达式)DUP操作符的后面为一个加圆括号的表达式。DUP表示的功能是把表达式重复预置,重复的次数由DUP前面的常数决定。例如:TABADB120DUP(0);分配120个字节,并预置为零。TABBDW1000DUP(?);分配1000个字,不改变原先内容。TABCDB10DUP(′WELCOME′,0AH,0BH);表达式由一个字符串‘WELCOME’和两个常数0AH,0BH组成,并重复预置;10次。第二十页,共270页。还应指出,DUP可以重叠使用,例如:TABDDB2DUP(0,3DUP(1))DW100DUP(5DUP(5),38FBH)第一句是用DB定义的,表达式的外括号中的3DUP(1)表示把由DB定义的预置为1的字节数重复3次。这样,2DUP(0,3DUP(1))=2DUP(0,1,1,1)。再根据定义,把(0,1,1,1)重复2次,这样2DUP(0,3DUP(1))=0,1,1,1,0,1,1,1。整个语句的意思是:给命名为TABD的数组分配8个字节单元,并由低地址到高地址顺序放置0,1,1,1,0,1,1,1。第二个语句中(5DUP(5),38FBH)=(5,5,5,5,5,38FBH)。然后再把括号内由6个元素组成的数组重复100次。第二十一页,共270页。(5)地址表达式(只能用于DW或DD)。操作数为地址表达式时,应遵循下列规则:①当用DW定义地址表达式时,地址表达式中的变量名称表示该变量的第一个存储单元的偏移地址,地址表达式中的标号表示它所代表的指令(或伪指令)的第一个字节的偏移地址。②当用DD定义地址表达式时,低位字用于预置偏移地址,高位字用于预置段地址,这些数值都是在定位时装入的。③地址表达式中的变量或标号可与常数值相加减。对于变量来说,运算结果的类型不变;对标号来说,运算结果仍表示原标号所在段中的偏移地址。第二十二页,共270页。④变量或标号不能与变量或标号相加,但可相减,结果是没有属性的纯数值。定义地址表达式举例如下:A1DWVALUE;定义变量A1为VALUE的偏移地址。A2DWVALUE+5;定义变量A2为VALUE第6个字节的偏移地址。A3DWVALUE-3;定义变量A3为VALUE前3个字节的偏移地址。A4DDVALUE;高位字为VALUE所在段的段地址,低位字为VALUE的 偏移地址。第二十三页,共270页。定义变量的伪指令的功能是在变量名所对应的地址开始的内存区依次存入各项值。当同时有几个变量定义语句时,将按照由上到下书写顺序,由低地址到高地址给每个变量语句中的表达式分配存储单元。例如:DATA1DB20HDATA2DW0204H,100HDATA3DB(-1*3),(15/3)DATA4DD12345HDATA5DB′0123′DATA6DW′Ab′,′C′,′D′DATA7DB?DATA8DD?DATA9DB5DUP(00)

DATA10DW3DUP(?)第二十四页,共270页。图6.2各变量在内存中分配的单元第二十五页,共270页。4.表达式(1)操作数。一个操作数在内容上可能代表一个数据,也可能代表一个存储单元的地址。对于数据,最简单的表达方式就是用常数形式表示,如20H,1234H,0FDH。汇编语言源程序中也常用标号来表示数据,如可用PORTA表示一个端口地址号,而在源程序中应对PORTA作出定义,使它等于某个常数。在源程序中,存储器地址常用标识符(也称标号)来表示。如规范程序中常用START、MOVE、CLOSE作为标号。源程序中的地址标号常常作为转移指令的转移地址或调用指令的调用地址。这些标号所代表的具体的地址值应由段地址和偏移地址两部分组成。第二十六页,共270页。(2)运算符。用一个运算符可以对一个或几个操作数进行运算,构成一个表达式。源程序中表达式经汇编后为一个值。汇编语言中有5类运算符,即①算术运算符(ArithmeticOperators);②逻辑运算符(LogicalOperators);③关系运算符(RelationalOperators);④分析运算符(AnalyticOperators);⑤综合运算符(SyntheticOperators)。①算术运算符包括加(+)、减(-)、乘(*)、除(/)和取模运算(MOD)。取模运算是取两数相除的余数,但两操作数必须为正整数。例如

82MOD16结果为2(相当于取低4位的值)。B5HMOD20H结果为21(相当于取低5位的值)。20HMOD7结果为4。第二十七页,共270页。②逻辑运算符。逻辑运算符包括与(AND)、或(OR)、非(NOT)和异或(XOR)。逻辑运算符又能对常数进行运算,所得的结果也是常数。两数进行逻辑运算是两数的对应位按位进行相应的逻辑运算。例如:11001100BAND11110000B;结果为11000000B。11001100BOR11110000B;结果为11111100B。 NOTFFH;结果为00H。11001100BXOR11110000B;结果为00111100B。

第二十八页,共270页。应注意的是,逻辑操作符和逻辑运算指令的操作助记符是相同的。只有当它们出现在指令的操作数部分时,汇编程序才将它看成是逻辑运算符。例如:ANDDX,PORTAAND0FEHAND操作助记符逻辑运算符第二十九页,共270页。③关系运算符。关系运算符有:相等EQ(Equal)、不等NE(NoEqual)、小于LT(LessThan)、大于GT(GreaterThan)、小于或等于LE(LessthanorEqual)、大于或等于GE(GreaterthanorEqual)。参加关系运算的两个操作数必须都是操作数或者是同一段中的存储单元地址,结果总是一个数值。当关系成立时,其结果为全1,当关系不成立时,其结果为全0。例如:MOVBX,PORTLT5表示如果PORT的值确实小于5,则汇编后得到的代码等效于指令MOVBX,0FFFFH。第三十页,共270页。如果PORT的值大于或等于5,等效于指令MOVBX,0。所以关系运算符一般不单独使用,往往和逻辑运算符组合起来使用。例如:MOVBX,((PORTLT5)AND20)OR((PORTGE5)AND30)表示当PORT小于5时,上述指令等效于MOVBX,20当PORT大于或等于5时,上述指令等效于MOVBX,30第三十一页,共270页。④分析运算符和综合运算符。利用分析运算符可以把一个存储单元地址分解为段地址和偏移量。利用综合运算符可以规定存储单元的性质。ASM汇编语言的分析运算符有OFFSET、SEG、TYPE、SIZE和LENGTH。如表6.1所示。例如:MOVDX,OFFSETDATA1;取出标号DATA1的偏移量到DX中。MOVAX,SEGDATA1 ;取出DATA1的段地址送到DS中。MOVDS,AX

第三十二页,共270页。表6.1分析运算符表达式带分析运算符的表达式表达式的意义OFFSET变量名或标号取出变量名或标号所在段的偏移地址SEG变量名或标号取出变量名或标号所在段的段地址TYPE变量名或标号取出变量名或标号的类型SIZE变量名取出变量的大小LENGTH变量名取出变量的长度第三十三页,共270页。类型TYPE运算符用来说明变量名或标号分配存储单元的类型,如是字节分配类型,对应值为1;如是字分配类型,对应值为2;如是双字分配类型,对应值为4。如表6.2所示。表6.2存储单元分配类型和对应值存储单元分配类型对应值字节1字2双字4第三十四页,共270页。变量的类型是由伪指令DB、DW和DD来定义的。比如:

DATA3DB(-1*3),(15*3);定义DATA3为字节变量。

此时TYPEDATA3对应的值为1,以字节分配存储单元。又如TABADB20DUP(?),那么TYPETABA也等于1。运算符LENGTH对于变量中使用DUP的情况,汇编程序将给出分配给该变量的单元数(分配单元可以以字节、字或双字为单位计算),而对于其它情况则给出值1。例如:

DATA6DW′Ab′,′C′,′D′

此时LENGTHDATA6等于1。又如: ABCDW100DUP(?)此时LENGTHABC等于100。第三十五页,共270页。运算符SIZE用来计算一个变量存储区所占用的字节数。同样,以ABC变量为例,SIZEABC等于200,因它占用的字节为200(100个字)。由上可知,SIZE、LENGTH和TYPE之间有如下关系:SIZE=LENGTH*TYPEASM的综合运算符有PTR和THIS。PTR用来对存储单元规定类型。PRT运算符所表示操作数的格式为类型PTR表达式格式中的类型可以是:BYTE、WORD、DWORD、NEAR和FAR。前3个类型是变量类型,后两个是标号类型。格式中的表达式可以是变量名、标号或其它地址表达式。第三十六页,共270页。PTR运算符的功能是用来重新定义已定义过的变量或标号的类型。例如:

MOVBYTEPTR[1000],0

此语句是用BYTE和PTR规定地址号为1000存储单元为字节单元。所以执行结果是将[1000]单元清零。如使用下列语句:

MOVWORDPRT[1000],0此语句是规定地址号1000存储单元为字单元,所以执行结果应将[1000]及[1001]两单元清零。第三十七页,共270页。又如,若已定义DATA3是字变量,则程序中需将它作为字节变量使用时,必须用PTR来重新定义其类型。可以用如下语句:MOVBYTEPTRDATA3,AL

它的功能是将(AL)送至DATA3对应的一个字节中。应指出变量DATA3仅在此语句中临时被定义成字节变量,DATA3原先定义的字变量类型没有修改。THIS综合运算符也可以用来改变存储区的类型,称类型指定运算符。THIS运算符的运算对象是类型(BYTE、WORD、DWORD)或距离(NEAR、FAR),用于规定所指变量或标号类型属性或距离属性。例如:

XYZEQUTHISBYTE第三十八页,共270页。此等价语句的功能是把字节类型BYTE属性赋予变量XYZ。它等效于下述表达式:

BYTEPTRXYZTHIS可提高访问标号的灵活性,如:FAROUTEQUTHISFAR此语句的功能是把段间距离属性FAR赋予标号FAR-OUT。第三十九页,共270页。6.1.5伪指令1.方式伪指令(1).8086。在这条伪指令后,汇编程序将在8086/8088方式下操作,实际上这是微处理器的默认操作状态。(2).386。在这条伪指令后,汇编程序将在80386方式下操作。如果想利用32位寄存器,必须加上这条伪指令。第四十页,共270页。2.赋值伪指令EQU在汇编语言程序中,当某个表达式被多次引用时,常采用给这个表达式赋予一个名称,这样源程序中就可以以名称代替表达式;另外常使用标号来代表数据、数据地址或程序地址。这种赋予表达式或数据/地址以名称/标号的伪指令EQU有两种格式,即①表达式名称EQU表达式②新标号EQU老标号第四十一页,共270页。在①种格式中,表达式可以是常数或者地址表达式,例如:ABCEQU2000H;表示名称ABC就是等价于数值2000H。XYZEQU[BP+5];名称XYZ就代表地址表达式[BP+5]。ECONEQUE7HMOD10;ECON是代表取模运算后的余第四十二页,共270页。在②种格式中,可以对以前已经赋过值的标号以新的标号,例如:

AADEQUPAR-3;新标号AAD等价于老标号PAR-3的值。COUNTEQUCX;使COUNT和寄存器CX具有相同的意义。如果有了上列语句,则指令语句MOVAL,AAD等价于MOVAL,PAR-3MOVAX,COUNT等价于MOVAX,CX第四十三页,共270页。3.定义变量伪指令前面已经提及定义变量的伪指令,就是给变量分配存储单元。这些伪指令是DB、DW、DD、DQ、DT。DB用来定义字节,DW定义字,DD定义双字,DQ定义4个字,DT定义10个字。这些伪指令的格式及用法见前述。第四十四页,共270页。

4.定义存储单元类型的伪指令BYTE、WORD、DWORD定义存储单元的伪指令并不是单独使用,而是和指令结合起来使用的。利用这些伪指令,对存储单元类型进行规定。例如:MOVBYTEPTR[DI],00MOVWORDPTR[1000],00INCBYTEPTR[DI]JMPDWORDPTR[2000]第四十五页,共270页。

5.LABEL本条伪指令用于定义标号名称和属性,它和下一条指令共享存储器单元。格式: 名字LABEL类型例如:BYTE-ARRAYLABELBYTEWORD-ARRAYDW100DUP(?)在第二条语句中指明了有100个字存储单元,它们的符号地址名为WORD-ARRAY,但在第一行说明这100个字存储单元可以看成200个字节存储单元。符号地址名为BYTE-ARRAY。第四十六页,共270页。这样,当我们访问存储器操作时,就可以有两种观点:(1)MOVWORD-ARRAY,0;是把第一个字置为0。(2)MOVBYTE-ARRAY,0;是把第一个字节置为0。利用LABEL伪指令,对存储器单元就可以有不同的划分,这为访问存储器单元提供了较大的灵活性。第四十七页,共270页。

6.SEG和OFFSETSEG操作符返回存储器地址操作数的段地址部分,而OFFSET返回存储器地址操作数的段内偏移地址部分。例如:

…NUMBER-1DD?…MOVAX,SEGNUMBER-1MOVDS,AX ;段地址进入DS。MOVSI,OFFSETNUMBER-1;偏移地址进入SI。第四十八页,共270页。7.TYPE、SIZE和LENGTH表6.3存储器地址操作数类型值存储器操作数类型值(DB)字节数据1(DW)字数据2(DD)双字数据4(DF)三字数据6(DQ)四字数据8(DT)五字数据10NEAR指令单元-1FAR指令单元12第四十九页,共270页。这里,字节、字等的类型就是它们所占用的字节数,而NEAR和FAR指令单元的类型值没有物理意义。SIZE和LENGTH只应用于存储器地址操作数。LENGTH返回一个你定义的数的尺寸的单元数。SIZE则返回存储器地址操作数占用的字节数。例如:LARGE-NUMDD40DUP(0)这里是按双字尺寸分配存储单元的,所以LENGTH(LARGE-NUM)是40,而SIZE(LARGE-NUM)是160。可以看出,如果X是地址操作数,则

SIZE(X)=(LENGTH(X))*(TYPE(X))第五十页,共270页。8.段定义伪指令(1)SEGMENT/ENDS伪指令。伪指令SEGMENT和ENDS总是成对使用的。用这对伪指令来指定段的名称和范围,还可指明段的定位类型(aligntype)、组合类型(combinetype)和分类名。段定义伪指令的格式为

段名SEGMENT[定位类型][组合类型][分类名]…}本段程序内容(指令语句或伪指令语句)段名ENDS从SEGMENT伪指令之后出现的指令和伪指令都被认为是在该段之内,直至ENDS出现为止。第五十一页,共270页。段定义格式中,带有‘[]’部分根据需要可有可无。还应指出,当用于定义数据段、附加数据段和堆栈段时,处于SEGMENT/ENDS伪指令中间的语句,只能包括伪指令语句,不能包括指令语句,一般格式为

段名SEGMENT…}数据定义,存储单元分配等伪指令语句段名ENDS当由SEGMENT/ENDS定义代码段时,中间的语句可包括指令语句和与指令有关的伪指令语句。一般格式为

段名SEGMENT…}指令语句和与伪指令有关的伪指令语句段名ENDS第五十二页,共270页。段定义格式中,各部分的用法说明如下:段名:所定义段的名称。段名是标识符,同一段的SEGMENT/ENDS伪指令前的段名必须一致。一个段一经定义,其中指令的标号、变量等在段内的偏移地址就已排定,它们都在同一个段地址控制之下,整个段占用的存储空间大小也就确定。由SEGMENT/ENDS伪指令所定义的段,通常小于64K单元,而且经过汇编和连接,定义的各段不互相覆盖。一个源程序模块的典型结构如下:STACK-SEGSEGMENT;STACK-SEGENDS;…定义堆栈段第五十三页,共270页。DATA-SEGSEGMENT;DATA-SEGENDS;EXTRA-SEGSEGMENT;EXTRA-SEGENDS;CODE-SEGSEGMENT;START:CODE-SEGENDS;ENDSTART;源程序模块结束………定义数据段定义附加数据段定义代码(即指令)段第五十四页,共270页。段定义格式中SEGMENT伪指令后,用‘[]’括起来的不是规定的语法符号,而是表示该项是可选的,有时可以全部省略。当它们存在时,用于指明段间的联系形态,说明段定义的辅助属性。现说明如下:①定位类型。定位类型给出实际段起点的类型。它有PAGE、PARA、WORD、BYTE四种类型。PAGE:表示相应的段必须从某一页(256个字节)的边界开始。即段的起始地址能为256整除。此时20位的段地址为PAGE=××××××××××××00000000B第五十五页,共270页。PARA:表示段的起点是从存储器中的某一个节(一节等于16个字节)的边界开始。也即段的起始地址能被16整除。此时20位的段起始地址为PARA=××××××××××××××××0000BWORD:表示段的起点可以从任何一个字的边界(偶地址)开始。即地址能被2整除。段起始地址为WORD=×××××××××××××××××××0BBYTE:表示段的地址可以从存储器的任何地址开始。段起始地址为BYTE=××××××××××××××××××××B对于PAGE和PARA类型其段内的偏移地址都是从0开始的。而对WORD类型,段内偏移地址不一定从0开始,合理选择定位类型,能够使得在进行段和模块的定位连接时,可充分地利用存储器空间。第五十六页,共270页。②组合类型。组合类型在模块式程序设计中表示该段和其它同名段间的组合连接方法。如果在SEGMENT伪指令后面没有指明组合类型,则汇编程序ASM认为这个段是不准备与别的段相连接的。组合类型有以下5种选择:PUBLIC:表示该段可与模块连接时所遇到的其它同名段在满足定位类型的前提下依次连接起来。连接的顺序由连接程序LINK确定。COMMON:表示该段与别的模块中的所有其它同名同类别段共享相同的存储空间。即各段都是从相同的地址开始,具有同样的段地址,且互相覆盖。连接后,段的长度等于最长的COMMON段的长度。第五十七页,共270页。AT表达式:表示相应段定位在由表达式求值得到的节边界地址上。表达式也可以是一个常数。例如,AT2345H表示该段定位在实际物理地址23450H处。STACK:与PUBLIC组合类型的处理方式相同,即把不同模块中带有STACK组合类型的同名段连接起来,使这些同名段都从同一基地址开始。但STACK组合方式仅用于堆栈段。MEMORY:表示在连接时,本段应装在被连接的其它段之上,即在同名段中具有最高的地址。若连接时具有MEMORY组合类型的段不止一个,则只有第一段才当成MEMORY组合类型来处理,其它的段将重叠,即按COMMON组合类型来处理。第五十八页,共270页。③类名。类名是程序员任选的一个字符串,使用时必须用单引号括起来‘类名’。连接时,将把不同模块中相同‘类名’的各段在物理地址上相邻的连接在一起,其顺序则与LINK时提供的各模块顺序一致。第五十九页,共270页。(2)ORG伪指令。伪指令ORG用来规定目标程序存放单元的偏移量。它的格式如下:

ORG表达式其中表达式以65536(216)为模进行计算,计算结果应是一个不为负的常数。若表达式中有标识符,则标识符必须是已经定义过的。汇编程序ASM规定ORG伪指令不能带标识符。例如: START:ORG2000H是非法语句。第六十页,共270页。如果在源程序中的第一条指令用了如下伪指令:ORG2000H,则汇编程序将把指令指针IP的值置成2000H,目标程序的第一个字节将放置在2000H单元,后面的程序就会依次顺序存放。当遇上另一个ORG语句时,目标程序的存放地址才会从新的ORG语句指定的地址单元存放。例如,若当前的(IP)=2400H,这时若又遇到如下ORG语句:

ORG2464H则汇编程序会修改IP内容,使(IP)=2464H,并以此存储单元开始存放目标程序。这样就保留了100个字节的存储空间。ORG伪指令可以放置在源程序中的任何位置。第六十一页,共270页。(3)ASSUME伪指令。ASSUME伪指令语句用来告诉汇编程序在指令执行期间内存的哪一段是数据段,哪一段是堆栈段,哪一段是代码段。ASSUME伪指令语句的格式如下:

ASSUME段寄存器名:段名符[,段寄存器名:段名符,…]上述格式中[]内的内容可有可无。例如:

ASSUMECS:MYCODE,DS:MYDATAASSUMEES:MYEXTRA,SS:MYSTACK第六十二页,共270页。这两个语句是将所定义的段MYCODE、MYDATA、MYEXTRA和MYSTACK分别置于段寄存器CS、DS、ES和SS的控制之下。ASSUME语句只能安排在代码段内,一般应排在代码段作为首始指令。ASSUME语句中的‘段寄存器名:段名符’可以有一项,也可以有多项,如果一行写不下,可分成两个ASSUME语句。一个源程序模式至少包括一个段,当指令(即代码)、数据及堆栈区都将集中在一个段内时,ASSUME语句的格式应该是为

ASSUMECS:MYCODE,DS:MYCODE,ES:MYCODE,SS:YCODE第六十三页,共270页。除了CS以外,各个段寄存器的实际值,还要用MOV指令来赋值。例如:…

MYCODESEGMENTASSUMECS:MYCOED,DS:MYDATA,ES:MYEXTRA,SS:MYSTACKSTART:MOVAX,MYDATAMOVDS,AXMOVAX,MYEXTRAMOVES,AXMOVAX,MYSTACKMOVSS,AX…MYCODEENDS …第六十四页,共270页。

9.过程定义伪指令PROC,ENDP,NEAR,FAR在ASM语言中,过程的含义和子程序是一样的。一个过程可以被其它程序所调用,它的最后一条指令总是返回指令,用以控制此过程在执行完毕后,返回到主程序。定义过程的伪指令PROC/ENDP总是成对出现的,在这两条伪指令间的内容就作为一个过程,即一个子程序。有关PROC/ENDP伪指令的格式定义在第4章中已作了介绍,现仅举例说明PROC/ENDP等一组伪指令的用法。下面是实现多字节BCD码相加的完整的程序片段:第六十五页,共270页。DATASEGMENT;定义数据段。FIRSTDB11,22,33,44;第一个加数。SECONDDB55,66,77,88;第二个加数。SUMDB4DUP(?);存放结果单元。DATAENDSSTACKSEGMENT;定义堆栈段。STADB20DUP(?);设置堆栈长度为20个字节。TOPEQULENGTHSTASTACKENDSCODESEGMENT;定义代码段。ASSUMECS:CODE,DS:DATA,SS:STACK第六十六页,共270页。START:MOVAX,DATA;装入段寄存器实际值数据。 MOVDS,AX MOVAX,STACK;装入段寄存器实际值堆栈。 MOVSS,AX MOVAX,TOP ;设置堆栈指针。 MOVSP,AX MOVSI,OFFSETFIRST;SI指向第一个加数。 MOVDI,OFFSETSUM;DI指向结果单元。 MOVBX,OFFSETSECOND;BX指向第二加数。 MOVCX,04 ;共4个字节长。 CLD ;清方向标志。 CLC ;清进位标志。第六十七页,共270页。ADITI:CALLAAA;调用多字节加法子程序。 LOOPADITI… ;继续后面主程序。…AAA1PROCNEAR;单字节加法子程序。LODSB;取第一个加数。ADCAL,[BX];相加。DAA;十进制调整。STOSB;结果送DI所指单元。INCBX;修改指针。RET;返回。AAAENDP;子程序结束。CODEENDS;程序段结束。ENDSTART;程序结束。第六十八页,共270页。10.定义结构的伪指令STRUC/ENDS(1)结构的定义。结构伪指令的格式如下:

结构名称STRUC…结构名称ENDS

如果DB、DW或DD语句包括变量标识符,则该标识符表示一个字段的开始,称为字段标识符。例如,对上述所说的学生学业管理可采用以下所示的结构形式:由DB、DW、DD伪指令所组成的语句序列第六十九页,共270页。STUDENT-RECORDSTRUCNAMEDB′LiPing′SEXDB0,0formale,1forfemaleAGEDB25HNUMBERDB′??????′MATHDB91HPHYSICALDB85HCIRCUITDB95H…STUDENT-RECORDENDS第七十页,共270页。(2)结构的存储分配和预置。为了给结构分配存储空间或预置,必须有一个援用该结构的语句,其格式如下: 变量结构名称〈赋值说明〉其中结构名称是指STRUC伪指令中的结构名称(在前面的例子中为STUDENT-RECORD),变量与结构的起始点相对应,另外变量名要与字段标识符一起使用方可访问结构中的各个字段(对上述的例子,变量名可用所管理的学生名表示,也可以用其它方法为变量命名)。第七十一页,共270页。赋值说明必须写在尖括号‘〈〉’内,它由一系列常数表达式组成,一个字段一个表达式,由逗号分开;如果某个字段有某n个字段使用结构定义中的预赋值,则相应的表达式可省缺,但应保留逗号;如果全部表达式都省缺,则只要写一对尖括号;如果省缺的是最后面的一些字段,则可以省去逗号。此外,对字符串常量所表示的字段要替换的话,若替换的字符长度大于原来形式参数的长度,汇编程序将自动截去多出的字符;若替换字符长度小,则用最后的那个字符填满剩余的存储空间。例如,对上述的例子援用语句可以是:LiPingSTUDENT-RECORD〈,,,′891011′〉LuiYiSTUDENT-RECORD〈′LuiYi′,1,′891011′,80H〉第七十二页,共270页。(3)对结构的访问。通过援用语句对结构进行存储空间分配和预置之后,结构及其字段就以变量的形式出现,可以像使用其它变量一样使用。但对结构的访问必须用变量路径名的方法进行,路径名的格式为变量名·字段名例如,对于前面的例子,若需要将学生A的年龄传送到寄存器AL,则可以使用下列指令语句:

MOVAL,LiPing·AGE如果BX中存有变量LiPing的偏移地址,则下列语句与上述语句是等效的:MOVAL,[BX]·AGE第七十三页,共270页。11.IFELSEENDIF条件汇编伪指令MASM提供了功能强大的条件汇编伪指令,使用它的一般格式是:IF ;如果条件成立…[ELSE];[否则]…ENDIF;结束条件汇编语句第七十四页,共270页。其中IF有多种形式,它们是:IF操作数;如果操作数不等于0时。IFE操作数;如果操作数等于0时。IFDEF标号或变量;如果标号或变量已被定义时。IFNDEF标号或变量;如果标号或变量还没被定义时。IFB〈变量〉;如果变量为空时。IFNB〈变量〉 ;如果变量不为空时。IFIDN〈操作数1〉,〈操作数2〉;如果〈操作数1〉等于〈操作数2〉时。IFDIF〈操作数1〉,〈操作数2〉;如果〈操作数1〉不等于〈操作数2〉时。IF1 ;如果汇编程序在第一遍扫描时。IF2 ;如果汇编程序在第二遍扫描时。在IF的形式中,尖括号“〈〉”中内容是必需的。第七十五页,共270页。

12.逻辑运算伪指令AND、OR、XOR、NOT按位操作,运算规则与它们作为指令时一样,但只能用于算术表达式中。与指令AND、OR、XOR、NOT区别如下:作为指令时它们用在最前面,且目的操作数必须为寄存器或存储器操作数;作为伪指令时它们用在数学表达式中,操作数在它们的两边,可以都是立即数。例如:

ANDAX,CX ;AND作为指令。MOVAX,OFEHAND145H;AND作为伪指令。ANDDX,CXANDOFA4CH;第一个作为指令,第二个是伪指令。第七十六页,共270页。

13.访问外部标识符的伪指令EXTRN、PUBLIC当把若干个模块连接在一起时,必须解决其中的任一模块能够引用其它模块中的某些变量或标号的问题,这里引入的定义访问外部标识伪指令EXTRN和PUBLIC就是提供解决这个问题的方法。如果一个标识符只在一个模块中定义过,那么就说它相对这个模块是一个内部标识符或局部标识符;如果一个标识符在其模块内未定义过,而是在其它模块中定义,那么它就被称为相对该模块的外部标识符。第七十七页,共270页。对于只产生一个单一目标模块的汇编语言程序,它所访问的所有标识符必须是局部定义的,对于多模块程序来说,必须给汇编程序一个信息以说明其间的有些标识符是外部的,而不致被汇编程序把它们处理为一些无效的标识符。此外,为了允许其它模块访问一给定模块中的标识符,该给定模块必须包含一个标识符清单以说明其中的标识符可为其它模块访问。因此,每个模块可含有两个清单:一个清单标明它所要访问的其它模块的标识符;另一个清单是列出它所定义的,且为其它模块所访问的标识符。这两个清单依靠伪指令EXTRN和PUBLIC列出。第七十八页,共270页。EXTRN和PUBLIC伪指令语句的格式如下:EXTRN标识符:类型,…,标识符:类型PUBLIC标识符,…,标识符EXTRN伪指令语句中的标识符表示是外部的变量或标号,而PUBLIC伪指令语句中的标识符表示可供其它模块引用的变量或标号。在EXTRN伪指令中,若标识符为标号,则类型有NEAR或FAR;若标识符为变量,则类型有BYTE,WORD或DWORD。第七十九页,共270页。在语句INCVAR1中,若VAR1是外部变量,且对应于一个字,则含有该语句的模块中就必须有如下所示的一条伪指令语句:EXTRN…,VAR1:WORD,…而在定义VAR1模块中就必须含有下列语句:PUBLIC,…,VAR1,…第八十页,共270页。

14.源程序结束伪指令END伪指令END用来表明END语句处是源程序的终结。其格式如下:END表达式这里的表达式通常就是程序第一条指令的语句标号。这样,程序在汇编、连接后,将目标代码装入内存之后准备要执行的起始地址由此标号所决定。当然,这个表达式也可以省去。下面是一个完整的源程序片断,从中可以看出END伪指令的用法:第八十一页,共270页。DATASEGSEGMENTVAR1DW7654HVAR2DW2345HRESULTDW?DATA-SEGENDSCODE-SEGSEGMENTASSUMECS:CODESEG,DS:DATA-SEGSTART:MOVAX,DATA-SEGMOVDS,AXMOVAX,VAR1SUBAX,VAR2MOVRESULT,AXCODE-SEGENDSENDSTART第八十二页,共270页。15.常用伪指令列表表6.4MASM伪操作符表第八十三页,共270页。续表第八十四页,共270页。续表第八十五页,共270页。续表第八十六页,共270页。续表第八十七页,共270页。续表第八十八页,共270页。续表第八十九页,共270页。续表第九十页,共270页。续表第九十一页,共270页。续表第九十二页,共270页。续表第九十三页,共270页。6.1.6宏指令及其使用1.宏指令、宏定义和宏调用宏指令是源程序中具有独立功能的一段程序代码。它可以根据用户的需要,由用户自己在源程序中定义。宏指令一经定义,便可在以后的程序中多次调用。宏定义由MASM宏汇编程序提供的伪指令实现,格式为宏指令名MACRO〈形式参数〉;…;ENDM宏体第九十四页,共270页。其中MACRO和ENDM均为伪指令,它们必须成对出现在源程序中,且必须以MACRO作为宏定义的开头,而以ENDM作为宏定义的结尾。MACRO和ENDM之间为宏体,是实现宏指令功能的实体。宏指令名(Macroname)是为宏指令起的名字,以供在源程序中调用该宏指令时用。形式参数(也称虚拟参数)的设置增强了宏指令的功能,使其更加灵活。形式参数的设置可根据需要而定,可用一个或多个(最多不超过132个),也可以没有。当有多个形式参数时,参数之间必须以逗号隔开。宏调用的格式为宏指令名〈实际参数〉第九十五页,共270页。例6.1设有如下4个宏定义:PUSHREGMACROPUSHAXPUSHBXPUSHCXPUSHDXPUSHSIPUSHDIENDM显而易见,这是一个无形式参数的宏定义。第九十六页,共270页。LOADWMACROPR,VAR MOVPR,VAR MOVAX,[PR] ENDM该宏定义有2个形式参数,它们都在操作数域,互相之间必须用逗号分开。SHIFTMACRON,REG,CCMOVCL,NS&CCREG,CLENDM第九十七页,共270页。根据以上宏定义,若需编一段程序,将某变量WVAR内容送AX寄存器,右移4位后,再存入WVAR变量处,则可采用宏调用方法编写如下程序段:LOADWSI,WVARSHIFT4,AX,ARSAVEWSI,AX,INC……第九十八页,共270页。相应的宏展开如下:

LOADWSI,WVAR+MOVSI,WVAR+MOVAX,[SI]SHIFT4,AX,AR+MOVCL,4+SARAX,CLSAVEWSI,AX,INC+MOV[SI],AX+INCSI……第九十九页,共270页。宏展开时,汇编程序在所展开的指令前加“+”,以便与其它指令区别。上述宏展开中LOADWSI,WVAR语句、SHIFT4,AX,AR语句及SAVEWSI,AX,INC语句是为程序阅读方便而提供的,不占内存单元。又若需将变量FIRST的内容取入BX,左移4位后再存入FIRST变量处,则有如下程序段:LOADWDI,FIRSTMOVBX,AXSHIFT4,BX,ALSAVEWDI,BX,INC……第一百页,共270页。宏展开后程序段如下:

+LOADWDI,FIRST+MOV DI,FIRST+MOV AX,[DI]MOV BX,AXSHIFT 4,BX,AL+MOV CL,4+SAL BX,CL+SAVEWDI,BX,INC+MOV DI],BX+INC DI……第一百零一页,共270页。2.宏嵌套宏定义中允许使用宏调用,但所调用的宏指令必须先定义过。不仅如此,宏定义中还可以包含宏定义。例6.2设计一个程序段实现下列运算:FIRST1*FIRST2+SECOND1*SECOND2并将结果存储起来(不考虑最后结果溢出)。MULTIPLYMACROOPR1,OPR2,RESULT MOVAL,OPR1 IMULOPR2 MOVRESULT,AX ENDM第一百零二页,共270页。ADDMULTMACROREG,VAR1,VAR2 MULTIPLYFIRST1,FIRST2,MULT1 MULTIPLYSECOND1,SECOND2,MULT2 MOVREG,VAR1 ADDREG,VAR2 MOVSUM,REG ENDM

可以看出,在ADDMULT宏定义中两次调用了定义过的宏指令MULTIPLY。第一百零三页,共270页。若有宏调用:ADDMULTAX,MULT1,MULT2则宏展开后的程序段如下:

MULTIPLYFIRST1,FIRST2,MULT1+MOV AL,FIRST1+IMULFIRST2+MOVMULT1,AXMULTIPLYSECOND1,SECOND2,MULT2+MOVAL,SECOND1+IMULSECOND2+MOVMULT2,AXADDMULTAX,MULT1,MULT2+MOVAX,MULT1+ADDAX,MULT2+MOVSUM,AX……第一百零四页,共270页。例6.3采用宏定义体内包含宏定义的方法设计一个运算宏指令。宏定义:DEFCALCUMACROCALCULATION,OPERATORCALCULATIO

温馨提示

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

评论

0/150

提交评论