第4章汇编语言程序设计本章主要内容4.1汇编语言程序设计概述4.2伪指令4.3汇编语言程序设计基本方法4.4中断调用4.1汇编语言程序设计概述汇编语言(AssemblyLanguage)是一种以处理器指令系统为基础的低级程序设计语言,它采用助记符表达指令操作码,采用标识符号表示指令操作数利用汇编语言编写程序的主要优点是可以直接、有效地控制计算机硬件,因而容易创建代码序列短小、运行快速的可执行程序汇编语言适合用于编写低层、直接控制硬件的程序;加解密、病毒防治等信息安全程序的编程分析汇编语言程序设计的过程是与其他高级语言程序设计大致相同,用汇编语言编写的程序称为汇编语言程序或源程序(SourceProgram)。汇编语言源程序不能直接在计算机上运行,需要将它翻译成机器语言程序(也称目标代码程序,ObjectProgram)。这个翻译过程为汇编。完成汇编任务的程序(软件)称为汇编程序。汇编程序完成以下几个任务:将汇编语言源程序翻译成目标代码程序;按指令要求自动分配存储区(包括程序区、数据区等);自动把源程序中以各种进制表示的数据都转换成二进制形式的数据;计算表达式的值;对汇编语言源程序进行语法检查,并给出语法出错的提示信息。4.1.1汇编语言源程序的结构汇编语言程序由若干个段组成。按照各段功能的不同,分别有代码段、数据段、堆栈段和附加段。其中代码段是必须要定义的。每个段在程序中的顺序没有先后,段的数目也不受限制,但每个段必须有段名。汇编语言源程序格式举例DATASEGMENTMSGDB'HelloWorld!',13,10,'$'DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATABEGIN:MOVAX,DATAMOVDS,AXMOVAH,9LEADX,MSGINT21HMOVAH,4CH;返回DOSINT21HCODEENDSENDBEGIN汇编源程序框架举例(两个段的)DATASEGMENT;定义数据段……DATAENDSCODESEGMENT;定义代码段ASSUMECS:CODE,DS:DATASTART:;程序执行的起始地址MOVAX,DATAMOVDS,AX;段寄存器DS←数据段段地址……;程序的主体部分MOVAH,4CH;INT21H;结束程序运行并且返回DOSCODEENDSENDSTART;结束汇编汇编源程序框架举例(一个段的)CODESEGMENT;定义代码段ASSUMECS:CODESTART:;程序执行的起始地址……;程序的主体部分MOVAH,4CH;int21h;结束程序运行并且返回DOSCODEENDSENDSTART;结束汇编汇编语言源程序的特点采用段式结构汇编源程序通常包含若干个段,上例的程序有数据段和代码段这两个段,DATA、CODE分别为两个段的名字。每一段有明显的起始语句SEGMENT与结束语句ENDS,这些语句称为“段定义”语句。每一段由若干汇编语句构成汇编源程序每一段包含若干汇编语句。汇编语句的主体是汇编指令。一条语句写一行,为了清晰,书写语句时,注意语句的各部分要尽量对齐。汇编语言源程序的特点(续)每个汇编源程序需要一个启动标号汇编语言源程序需要一个启动标号作为程序开始执行时目标代码的入口地址。启动标号可以按照汇编语言的标号命名规则由程序员自己定义。常用的启动标号有START、BEGIN等。加入适当注释,可以提高程序的可读性为了提高程序的可读性,可以在汇编语句后以分号“;”为起始标志,加入注释。汇编语言和操作系统(DOS)的接口计算机一旦启动成功,由DOS掌握CPU的控制权。应用程序只是作为DOS的子程序,应用程序执行完,必须返回DOS。上述程序的第11、12行就是返回DOS的语句。4.1.1汇编语言的语句汇编语言的语句可以分为:指令语句伪指令语句1.指令语句指令语句是可执行语句,汇编后将产生目标代码,CPU根据这些目标代码执行并完成特定操作。每一条指令语句表达了计算机具有的一个基本能力,这种能力在目标程序执行时反映出来。指令语句的格式为:[标号:]指令助记符[操作数][;注释]【例4.2】指令格式示例BEGIN:MOVAX,DATAMOVDS,AX;把数据段的段地址送入DS2.伪指令语句伪指令语句,也称指示性语句,是不可执行语句,汇编后不产生目标代码,它仅仅在汇编过程中告诉汇编程序如何汇编源程序。伪指令语句可以告诉汇编程序哪些语句是属于一个段、是什么类型的段、各段存入内存应如何组装、给变量分配多少存储单元、给数字或表达式命名等。伪指令语句的功能是由汇编程序汇编源程序时完成的,不是由CPU执行目标代码时实现的。伪指令语句的格式为:[符号名]伪指令助记符[操作数][;注释]【例4.3】伪指令格式示例DATASEGMENTMSGDB‘HelloWorld!$’;定义显示字符串DATAENDS汇编语句格式说明(1)关于格式的几个组成部分汇编语句的格式中带中括号的部分是可选项。各部分之间必须用空格(SPACE)或水平制表符(TAB)隔开。操作数项由一个或多个表达式组成,它为执行语句所要求的操作提供需要的信息。注释项用来说明程序或语句的功能,注释项在汇编时不会产生目标代码。注释项可以跟在语句的后面。分号“;”是注释项的开始。当分号“;”作为一行的第一个字符时,表示注释占据一整行,常用来说明下面一段程序的能。汇编语句格式说明(续)(2)关于标号与符号名标号与符号名都称为名字。标号是可选项,一般设置在程序的入口处或程序跳转点处,表示一条指令的符号地址,在代码段中定义,后面必须跟上冒号“:”。符号名也是一个可选项,可以是常量、变量、段名、过程名、宏名,后面不能跟冒号。汇编语句格式说明(续)(3)名字的命名规则①合法符号:字母(不分大小写)、数字及特殊符号(“?”,“@”,“_”,“$”,“•”)。②名字可以用除数字外所有的合法符号开头。但如果是用到符号“·”,那么这个符号必须是第一个字符。③名字的有效长度不超过31个英文字符。④不能把保留字(如CPU的寄存器名、指令助记符等)用作名字。4.1.3汇编语言的数据数据是汇编语言语句的重要组成部分。汇编语言能识别的数据有:常量变量标号1.常量常量是没有任何属性的纯数值数据,它的值在汇编期间和程序运行过程中不能改变。汇编语言程序中的常量有:数值常量字符常量符号常量(1)数值常量在汇编程序中,数值常量可以用不同进制形式表示。二进制常量表示为以字母B(或b)结尾的由数字0和1组成的序列,例如,01100101B。八进制常量表示为以字母Q(或q)或O(或o)结尾的由数字0~7组成的序列,例如,145Q。(1)数值常量(续)十六进制常量表示为以字母H(或h)结尾的由数字0~9、字母A~F(或a~f)组成的序列,例如,653AH。十进制常量表示为以字母D(或d)结尾的由数字0~9组成的序列。汇编语句中的数据默认采用十进制表示形式,所以,采用十进制数时,也可省略结尾的字母。例如,101D或100。1.常量(续)(2)字符常量字符常量是用单引号括起来的单个字符,如'a'、'1'等。字符常量在操作中体现出的值是其ASCII码值。1.常量(续)(3)符号常量符号常量是用名字来标识的常量。以符号常量代替常量,可以增加程序的可读性及通用性。2.变量变量是存储单元的符号地址,这类存储单元的内容可以在程序运行期间被修改。变量以变量名的形式出现在程序中。同一个汇编程序中,变量只能定义一次。变量具有以下3种属性。段属性:变量所在段的段地址。偏移属性:变量所在段的段内偏移地址。类型属性:变量占用存储单元的字节数。3.标号标号是指令的符号地址,可用作控制转移指令的操作数。标号具有以下3种属性。段属性:标号所在段的段地址。偏移属性:标号所在段的段内偏移地址。类型属性:也叫距离属性,表示标号可作为段内或段间的转移特性2.汇编语言的操作符与表达式操作项是汇编语句中的一个重要组成部分,它可以由常量(常数)、寄存器、标号、变量或表达式组成。表达式是常量、寄存器、标号、变量与一些操作符相组合的序列,分为数值表达式和地址表达式两种。汇编程序在汇编时按照一定的规则对表达式进行计算后可以得到一个数值或地址值。(1)PTR格式:类型PTR变量/标号返回值:具有规定类型属性的变量或标号。典型应用:①重新指定变量类型例如,有如下数据定义:BUFWDW1234H,5678H则下列指令合法:MOVAX,BUFWMOVAL,BYTEPTRBUFW;临时改变BUFW的字属性为字节属性PTR典型应用(续)②指定内存操作数的类型在寄存器间接寻址、寄存器相对寻址、基址变址寻址或相对基址变址寻址等内存寻址方式中,往往很难判断出操作数的类型属性,例如:INC[BX]。此时,汇编将指示出错,为了避免出错,应对操作数类型加以说明,如下所示:INCBYTEPTR[BX];字节属性INCWORDPTR[BX][SI];字属性4.2.1符号定义伪指令符号包括汇编语言的变量名、标号名、过程名、寄存器名及指令助记符等。常用符号定义伪指令有:EQU“=”1.EQU伪指令格式:名字EQU表达式表达式可以是一个常数、已定义的符号、数值表达式或地址表达式。功能:给表达式赋予一个名字。定义后,可用名字代替表达式。在同一源程序中,一个名字只能用EQU定义一次。例如:PIXEQU64*1024;名字PIX代表数值表达式的值AEQU7BEQUA-22.等号(=)伪指令格式:名字=表达式功能:与EQU基本相同,区别是它可以对同一个名字重新定义。例如:COUNT=10MOVAL,COUNT…COUNT=5…4.2.2变量(数据)定义伪指令数据定义伪指令用来定义变量的类型,给存储器赋初值,给变量分配存储空间。源程序经汇编后,各个变量的数据即被存储在相应的内存单元中。格式:[变量名]数据定义伪指令操作数[,操作数,…]DATA_BYTEDB10,4,10H,01010101BDATA_WORDDW2*50,-5,‘A’例:1.操作数是常数或表达式,可以是数据,也可以是地址DATA_BYTEDATA_WORD数据定义及存储器分配伪操作的操作数0AH04H10H55H64H00HFBHFFH41H00H2.操作数也可以是字符串ARRAYDB‘HELLO’注意:当定义和初始化多于两个以上字符的字符串时,只能使用DB伪指令,不能使用DW和DD伪指令,例如下列定义,是错误的:STRINGDW‘ABCDEF’×应改成:STRINGDB‘ABCDEF’ARRAY数据定义及存储器分配伪操作的操作数48H45H4CH4CH4FH数据定义及存储器分配伪操作的操作数3.可保留空单元,操作数为“?”[例]ABCDB12H,?,24HDEFDW?,100H,1234HABC12H----24H--------00H01H34H12HDEF数据定义及存储器分配伪操作的操作数4.操作数字段用复制操作符DUP格式:REPEAT-COUNTDUP(OPERAND,.....,OPERAND)数据定义及存储器分配伪操作的操作数4.操作数字段用复制操作符DUP[例]ARRAY1DB2DUP(0,?)ARRAY2DB100DUP(?)ARRAY1的语句可等价于:ARRAY1DB0,?,0,?100个字节单元ARRAY100H----00H----------------------------ARRAY24.2.3段定义伪指令汇编源程序由段组成,每段大小不超过64KB,不同的段存放不同类型的数据。段定义伪指令用于汇编源程序中段的定义。相关指令有:SEGMENT、ENDS、ASSUME。段定义伪指令的最简格式如下:段名SEGMENT...段名ENDS注:段名不可缺少,开始和结尾的段名必须一致4.2.4ASSUME格式:ASSUME段寄存