1、第6章 汇编语言程序设计 第6章 汇编语言程序设计 6.1 汇编语言语法汇编语言语法 6.2 汇编语言程序设计汇编语言程序设计 6.3 汇编程序及上机过程汇编程序及上机过程 6.4 DOS及及BIOS功能调用功能调用 6.5 任务切换与混合语言编程任务切换与混合语言编程 第6章 汇编语言程序设计 6.1 汇编语言语法汇编语言语法6.1.1 计算机程序设计语言的演变计算机程序设计语言的演变 1.机器语言机器语言(Machine Language)任何计算机实际上只能直接识别设计微处理器时所规定好的,一整套用“0”、“1”数字代码表示的机器指令。这些机器指令的全体是指令系统。不同类型的CPU,其机
2、器语言必然是不同的。这种直接用机器指令来编制计算机程序的方法就称为机器语言程序设计。教学用的单板计算机一般都直接采用机器语言编程。这种直接用机器语言编程的方法难度大,阅读、查错和修改程序也很不方便。通常,只有当编程者对CPU指令系统比较熟悉,编写的程序较短时,才有可能直接用机器语言来写。人们为了摆脱编程中这种原始而低级的状态,就设法采用一组字母、数字或字符来代替机器指令,这样就产生了汇编语言的概念和方法。第6章 汇编语言程序设计 2.汇编语言汇编语言(Assembly Language)和机器语言相比,使用汇编语言来编写程序可以用助记符来表示指令的操作码和操作数,也可以用标号和符号来代替地址、
3、常量和变量。但由于不同CPU的指令系统的指令编码不同,因此与之相应的汇编语言亦不相同。由于这种符号化的语言使用了用英文字母缩写表示的助记符,便于识别与记忆。另外,汇编程序还引入了新的汇编指令伪指令和宏指令,使得采用汇编语言进行程序设计更为方便灵活。第6章 汇编语言程序设计 图 6.1 汇编程序的“翻译”作用 汇编语言源程序汇编程序Assembler机器语言目标程序第6章 汇编语言程序设计 3.高级语言高级语言(Highlevel language)低级语言编程方式阻碍了计算机在国民经济及日常生活中的推广应用。随着计算机科学的发展,软件、硬件技术在相辅相成、相互支持中不断改进与完善,逐步创造出许
4、多适用于不同应用场合的计算机高级语言,如BASIC、FORTRAN、COBOL、PASCAL、FORTH、C语言等。这些高级的程序设计语言,使用了更接近于人们的自然语言(英语)和习惯的教学语言来描述算法的执行过程,从而使编写的程序更加直观和简练。这些高级语言通常都包含有各种函数计算、字符串处理、数据I/O等功能。所以程序的编写、阅读和修改变得相当容易掌握和使用。第6章 汇编语言程序设计 高级语言无论是面向问题或面向过程,一般总是独立于具体机器的。程序员可不必了解机器的指令系统和内部的具体结构,而把精力集中在正确掌握语言的语法规则和算法的程序实现上。同样,高级语言也必须借助于更强有力的翻译系统编
5、译程序(Compiler)才能将源程序转换成相应的机器语言目标程序。与汇编程序不同,此处一条最简单的高级语言语句,可能对应着一组机器指令。第6章 汇编语言程序设计 6.1.2 为什么要用汇编语言编写程序为什么要用汇编语言编写程序 为什么还要学习和使用汇编语言呢?主要有以下几点:(1)汇编语言非常接近机器语言程序,通过编制汇编语言程序,可以更清楚地了解计算机的工作过程。(2)现在的微机系统中,底层的一些功能仍然靠汇编语言程序来实现。(3)汇编语言程序的效率通常高于高级语言程序。第6章 汇编语言程序设计 6.1.3 汇编语言的语句种类及其格式汇编语言的语句种类及其格式 1.指令语句指令语句 每一条
6、指令语句在汇编时都要产生一个可供机器执行的机器目标代码,所以这种语句又叫可执行语句。指令语句的格式如下:标号:(前缀指令)助记符(操作符);(注释)(1)标号。这是一个任选字段。标号是指令语句的标识符,在语句之首,必须以“:”作为结束符。第6章 汇编语言程序设计 标号的组成规则如下:必须由字母、数字(0,9)及特殊符号(?,-,$)组成,且必须以字母打头。字符总数限制在31个以内。不能使用属于系统专用保留字(Reserved word)。保留字主要有CPU中各寄存器名(如AX,CS);指令助记符(如MOV,ADD);伪指令(SEGMENT,DB);表达式中的运算符(如GE,EQ)和属性操作符(
7、如PTR,OFFSET,SEG等)。语句格式中带()的项,是可有可无的项。如果有此项时,书写时不能加()括号。在有些指令语句中,需要在助记符前加前缀指令(例如LOCK或REP),中间应用空格使两者分开,如REP MOVSB。第6章 汇编语言程序设计 (2)指令助记符。这是为指令操作码规定的符号。任何指令语句都需要此部分,它表示了指令语句的基本操作功能。如MOV是传送指令的助记符,ADD是加法指令的助记符。(3)操作数。操作数可以根据指令的功能需要,可不带操作数,带1个操作数或2个操作数,若有两个操作数时,中间用“,”号分开。例如,NOP;STD;INCSI;ADD BL,30H。而操作数与助记
8、符之间必须以空格分隔。(4)注释。注释是为方便程序人员阅读程序而加的说明。它既不影响源程序的汇编,也不会出现在目标程序中。通常并不要求每个汇编语句都应加注释。第6章 汇编语言程序设计 6.1.4 常数、标号、变量及表达式常数、标号、变量及表达式 1.常数常数 常数就是指令中出现的那些固定值,可以分为数值常数和字符串常数两类。例如,立即数寻址时所用的立即数,直接寻址时所用的地址,ASCII字符等都是常数。常数除了自身的值以外,没有其它属性的数值。在源程序中,数值常数按其基数的不同,可有二进制数、八进制数、十进制数、十六进制数等几种不同的表示形式。汇编语句中用不同的后缀加以区别。二进制数:数字后面
9、跟字母B。如:00101101B第6章 汇编语言程序设计 八进制数:用数字07表示,数字后跟字母Q或字母O。例如:177567 Q (或177567O)263 Q (或263O)十 进 制 数:数字后 跟 字 母 D 或 不 跟 字 母。例 如:17893D(或17893)。十六进制数:十六进制数用09及AF表示。后面跟字母H。如:B7H,2031H。还应指出,汇编语句中的数值常数的第一位必须是数字,否则汇编时将被看成是标识符。如常数B7H在语句中应写成0B7H,FFH应写成0FFH。第6章 汇编语言程序设计 字符串常数是由单引号 括起来的一串字符。例如:ABCDEFG和179。单引号内的字符
10、在汇编时都以ASCII的代码形式存放在存储单元中。如上述两字符串其ASCII代码分别为41H、42H、43H、44H,4BH和31H、37H、39H。字符串最长允许有255个字符。第6章 汇编语言程序设计 2.标号 标号是用符号表示的地址,称为符号地址,用以指示此指令语句所在的地址。标号有3个属性:段地址、偏移地址和类型。标号的段地址和偏移地址属性是指标号对应的指令首字节所在的段地址和段内的偏移地址。标号的类型属性有两种:NEAR和FAR类型。标号如定义成NEAR类型,表示标号仅在本段内被引用;如定义成FAR类型,表示标号可以在段间使用。在转移和调用指令中常将标号作为转移目标地址使用。第6章
11、汇编语言程序设计 3.变量变量 变量是与一个数据项的第一字节相对应的标识符,它表示该数据项第一字节在现行段中的偏移量。变量的值在程序运行期间可随时修改。变量具有3个属性:段地址(SEG):变量所在段的段地址;偏移地址(OFFSET):变量所在段内的偏移地址;类型(TYPE):变量的类型是所定义的每个变量所占据的字节数。第6章 汇编语言程序设计 在汇编语言中,变量是通过伪指令来定义的,其格式如下:变量名 DB 表达式;定义字节变量。变量名 DW 表达式;定义字变量。变量名 DD 表达式;定义双字变量。变量名 DQ 表达式;定义长字变量。变量名 DT 表达式;定义一个十字节变量。第6章 汇编语言程
12、序设计 上述伪指令的格式中的表达式可以有以下几种情况:(1)一个或多个常数或某个运算公式(其值应为常数)。当为多个常数或运算式时,其间用逗号隔开。在这种情况下,DB将给定常数定义为字节。DW将给定常数定义为字(两个字节),并给它分配两个存储单元,低位字节数占低地址单元,高位字节数占高地址单元。DD将给定常数定义为双字,分配4个存储单元。同理,DQ则分配8个存储单元,DT分配10个存储单元。当定义的变量有几个操作数时,则应从左到右由低地址向高地址顺序排列所定义的常数。第6章 汇编语言程序设计 (2)带引号的字符串。字符串必须用单引号括住,字符串的字符不超过255个。DB对每一个字符分配一个存储单
13、元,字符是由左向右按地址递增的顺序排列。例如 KF DB ABC;按41H、42H、43H的顺序由低地址到高地址分配存储地址。当操作数有多个字符串时,也是从左到右按地址递增顺序分配各字符串的存放单元。第6章 汇编语言程序设计 (3)用问号作为表达式。不带引号的问号是一个保留字,它可用作数据类型伪指令DB、DW、DD语句中的表达式。用它告诉汇编程序,留出DB、DW、DD所分配的存储单元,原先内存内容不改变。例如:SUR DW?;预留一个字(二个字节)。SUM DB?;预留一个字节。第6章 汇编语言程序设计 (4)带DUP(重复方式)表达式。DUP是表达式中的一个操作符。此时表达式的格式为 重复次
14、数 DUP(表达式)DUP操作符的后面为一个加圆括号的表达式。DUP表示的功能是把表达式重复预置,重复的次数由DUP前面的常数决定。例如:TABA DB 120 DUP (0);分配120个字节,并预置为零。TABB DW 1000 DUP (?);分配1000个字,不改变原先内容。TABC DB 10 DUP (WELCOME,0AH,0BH);表达式由一个字符串 WELCOME 和两个常数0AH,0BH组成,并重复预置;10次。第6章 汇编语言程序设计 还应指出,DUP可以重叠使用,例如:TABD DB 2 DUP (0,3 DUP(1)DW 100 DUP (5 DUP(5),38FBH
15、)第一句是用DB定义的,表达式的外括号中的3 DUP(1)表示把由DB定义的预置为1的字节数重复3次。这样,2DUP(0,3DUP(1)=2 DUP(0,1,1,1)。再根据定义,把(0,1,1,1)重复2次,这样2 DUP(0,3DUP(1)=0,1,1,1,0,1,1,1。整个语句的意思是:给命名为TABD的数组分配8个字节单元,并由低地址到高地址顺序放置0,1,1,1,0,1,1,1。第二个语句中(5 DUP(5),38FBH)=(5,5,5,5,5,38FBH)。然后再把括号内由6个元素组成的数组重复100次。第6章 汇编语言程序设计 (5)地址表达式(只能用于DW或DD)。操作数为地
16、址表达式时,应遵循下列规则:当用DW定义地址表达式时,地址表达式中的变量名称表示该变量的第一个存储单元的偏移地址,地址表达式中的标号表示它所代表的指令(或伪指令)的第一个字节的偏移地址。当用DD定义地址表达式时,低位字用于预置偏移地址,高位字用于预置段地址,这些数值都是在定位时装入的。地址表达式中的变量或标号可与常数值相加减。对于变量来说,运算结果的类型不变;对标号来说,运算结果仍表示原标号所在段中的偏移地址。第6章 汇编语言程序设计 变量或标号不能与变量或标号相加,但可相减,结果是没有属性的纯数值。定义地址表达式举例如下:A1 DW VALUE ;定义变量A1为VALUE的偏移地址。A2 D
17、W VALUE+5 ;定义变量A2为VALUE第6个字节的偏移地址。A3 DW VALUE-3 ;定义变量A3为VALUE前3个字节的偏移地址。A4 DD VALUE ;高位字为VALUE所在段的段地址,低位字为VALUE的 偏移地址。第6章 汇编语言程序设计 定义变量的伪指令的功能是在变量名所对应的地址开始的内存区依次存入各项值。当同时有几个变量定义语句时,将按照由上到下书写顺序,由低地址到高地址给每个变量语句中的表达式分配存储单元。例如:DATA1 DB 20H DATA2 DW 0204H,100H DATA3 DB (-1*3),(15/3)DATA4 DD 12345H DATA5
18、DB 0123 DATA6 DW Ab,C,D DATA7 DB?DATA8 DD?DATA9 DB 5 DUP(00)DATA10 DW 3 DUP(?)第6章 汇编语言程序设计 图 6.2 各变量在内存中分配的单元 20H04H02H00H01HFDH05H45H23H01H00H30H31H32H33H42H41H43H00H44H00H?00H00H00H00H00H?DATA1DATA2DATA3DATA4DATA5DATA6DATA7DATA8DATA9DATA1043210100:0020HFEDCBA9876543210100:0010HFEDCBA9876543 0002H
19、0001H0100:0000H段地址:偏移地址第6章 汇编语言程序设计 4.表达式表达式 (1)操作数。一个操作数在内容上可能代表一个数据,也可能代表一个存储单元的地址。对于数据,最简单的表达方式就是用常数形式表示,如20H,1234H,0FDH。汇编语言源程序中也常用标号来表示数据,如可用PORTA表示一个端口地址号,而在源程序中应对PORTA作出定义,使它等于某个常数。在源程序中,存储器地址常用标识符(也称标号)来表示。如规范程序中常用START、MOVE、CLOSE作为标号。源程序中的地址标号常常作为转移指令的转移地址或调用指令的调用地址。这些标号所代表的具体的地址值应由段地址和偏移地址
20、两部分组成。第6章 汇编语言程序设计 (2)运算符。用一个运算符可以对一个或几个操作数进行运算,构成一个表达式。源程序中表达式经汇编后为一个值。汇编语言中有5类运算符,即算术运算符(Arithmetic Operators);逻辑运算符(Logical Operators);关系运算符(Relational Operators);分析运算符(Analytic Operators);综合运算符(Synthetic Operators)。算术运算符包括加(+)、减(-)、乘(*)、除(/)和取模运算(MOD)。取模运算是取两数相除的余数,但两操作数必须为正整数。例如 82 MOD 16 结果为2(
21、相当于取低4位的值)。B5H MOD 20H 结果为21(相当于取低5位的值)。20H MOD 7 结果为4。第6章 汇编语言程序设计 逻辑运算符。逻辑运算符包括与(AND)、或(OR)、非(NOT)和异或(XOR)。逻辑运算符又能对常数进行运算,所得的结果也是常数。两数进行逻辑运算是两数的对应位按位进行相应的逻辑运算。例如:11001100B AND 11110000B ;结果为 11000000B。11001100B OR 11110000B ;结果为 11111100B。NOT FFH ;结果为 00H。11001100B XOR 11110000B ;结果为 00111100B。第6章
22、 汇编语言程序设计 应注意的是,逻辑操作符和逻辑运算指令的操作助记符是相同的。只有当它们出现在指令的操作数部分时,汇编程序才将它看成是逻辑运算符。例如:ANDDX,PORTA AND0FEH AND操作助记符 逻辑运算符 第6章 汇编语言程序设计 关系运算符。关系运算符有:相等EQ(Equal)、不等NE(No Equal)、小于LT(Less Than)、大于GT(Greater Than)、小于或等于LE(Less than or Equal)、大于或等于GE(Greater than or Equal)。参加关系运算的两个操作数必须都是操作数或者是同一段中的存储单元地址,结果总是一个数值
23、。当关系成立时,其结果为全1,当关系不成立时,其结果为全0。例如:MOV BX,PORT LT 5 表示如果PORT的值确实小于5,则汇编后得到的代码等效于指令MOV BX,0FFFFH。第6章 汇编语言程序设计 如果PORT的值大于或等于5,等效于指令MOV BX,0。所以关系运算符一般不单独使用,往往和逻辑运算符组合起来使用。例如:MOV BX,(PORT LT 5)AND 20)OR(PORT GE 5)AND 30)表示当PORT小于5时,上述指令等效于 MOV BX,20 当PORT大于或等于5时,上述指令等效于 MOV BX,30 第6章 汇编语言程序设计 分析运算符和综合运算符。
24、利用分析运算符可以把一个存储单元地址分解为段地址和偏移量。利用综合运算符可以规定存储单元的性质。ASM汇编语言的分析运算符有OFFSET、SEG、TYPE、SIZE和LENGTH。如表6.1所示。例如:MOV DX,OFFSET DATA1 ;取出标号DATA1的偏移量到DX中。MOV AX,SEG DATA1 ;取出DATA1的段地址送到DS中。MOV DS,AX 第6章 汇编语言程序设计 表表6.1 分析运算符表达式分析运算符表达式 带分析运算符的表达式 表达式的意义 OFFSET 变量名或标号 取出变量名或标号所在段的偏移地址 SEG 变量名或标号 取出变量名或标号所在段的段地址 TYP
25、E 变量名或标号 取出变量名或标号的类型 SIZE 变量名 取出变量的大小 LENGTH 变量名 取出变量的长度 第6章 汇编语言程序设计 类型TYPE运算符用来说明变量名或标号分配存储单元的类型,如是字节分配类型,对应值为1;如是字分配类型,对应值为2;如是双字分配类型,对应值为4。如表6.2所示。表6.2 存储单元分配类型和对应值 存储单元分配类型 对应值 字节 1字 2双字 4第6章 汇编语言程序设计 变量的类型是由伪指令DB、DW和DD来定义的。比如:DATA3 DB(-1*3),(15*3);定义DATA3为字节变量。此时TYPE DATA3对应的值为1,以字节分配存储单元。又如TA
26、BA DB 20 DUP(?),那么TYPE TABA也等于1。运算符LENGTH对于变量中使用DUP的情况,汇编程序将给出分配给该变量的单元数(分配单元可以以字节、字或双字为单位计算),而对于其它情况则给出值1。例如:DATA6 DW Ab,C,D 此时LENGTH DATA6等于1。又如:ABC DW 100 DUP(?)此时LENGTH ABC等于100。第6章 汇编语言程序设计 运算符SIZE用来计算一个变量存储区所占用的字节数。同样,以ABC变量为例,SIZE ABC等于200,因它占用的字节为200(100个字)。由上可知,SIZE、LENGTH和TYPE之间有如下关系:SIZE=
27、LENGTH*TYPE ASM的综合运算符有PTR和THIS。PTR用来对存储单元规定类型。PRT运算符所表示操作数的格式为 类型 PTR 表达式 格式中的类型可以是:BYTE、WORD、DWORD、NEAR和FAR。前3个类型是变量类型,后两个是标号类型。格式中的表达式可以是变量名、标号或其它地址表达式。第6章 汇编语言程序设计 PTR运算符的功能是用来重新定义已定义过的变量或标号的类型。例如:MOV BYTE PTR1000,0 此语句是用BYTE和PTR规定地址号为1000存储单元为字节单元。所以执行结果是将1000单元清零。如使用下列语句:MOV WORD PRT1000,0此语句是规
28、定地址号1000存储单元为字单元,所以执行结果应将1000及1001两单元清零。第6章 汇编语言程序设计 又如,若已定义DATA3是字变量,则程序中需将它作为字节变量使用时,必须用PTR来重新定义其类型。可以用如下语句:MOV BYTE PTR DATA3,AL 它的功能是将(AL)送至DATA3对应的一个字节中。应指出变量DATA3仅在此语句中临时被定义成字节变量,DATA3原先定义的字变量类型没有修改。THIS综合运算符也可以用来改变存储区的类型,称类型指定运算符。THIS运算符的运算对象是类型(BYTE、WORD、DWORD)或距离(NEAR、FAR),用于规定所指变量或标号类型属性或距
29、离属性。例如:XYZ EQU THIS BYTE 第6章 汇编语言程序设计 此等价语句的功能是把字节类型BYTE属性赋予变量XYZ。它等效于下述表达式:BYTE PTR XYZ THIS可提高访问标号的灵活性,如:FAR OUT EQU THIS FAR此语句的功能是把段间距离属性FAR赋予标号FAR-OUT。第6章 汇编语言程序设计 6.1.5 伪指令伪指令 1.方式伪指令方式伪指令 (1).8086。在这条伪指令后,汇编程序将在8086/8088方式下操作,实际上这是微处理器的默认操作状态。(2).386。在这条伪指令后,汇编程序将在80386方式下操作。如果想利用32位寄存器,必须加上这
30、条伪指令。第6章 汇编语言程序设计 2.赋值伪指令赋值伪指令EQU 在汇编语言程序中,当某个表达式被多次引用时,常采用给这个表达式赋予一个名称,这样源程序中就可以以名称代替表达式;另外常使用标号来代表数据、数据地址或程序地址。这种赋予表达式或数据/地址以名称/标号的伪指令EQU有两种格式,即 表达式名称 EQU 表达式 新标号 EQU 老标号 第6章 汇编语言程序设计 在种格式中,表达式可以是常数或者地址表达式,例如:ABC EQU 2000H ;表示名称ABC就是等价于数值2000H。XYZ EQU BP+5 ;名称XYZ就代表地址表达式BP+5。ECON EQU E7H MOD 10 ;E
31、CON是代表取模运算后的余 第6章 汇编语言程序设计 在种格式中,可以对以前已经赋过值的标号以新的标号,例如:AAD EQU PAR-3 ;新标号AAD等价于老标号PAR-3的值。COUNT EQU CX ;使COUNT和寄存器CX具有相同的意义。如果有了上列语句,则指令语句 MOV AL,AAD 等价于 MOV AL,PAR-3 MOV AX,COUNT等价于 MOV AX,CX第6章 汇编语言程序设计 3.定义变量伪指令定义变量伪指令 前面已经提及定义变量的伪指令,就是给变量分配存储单元。这些伪指令是DB、DW、DD、DQ、DT。DB用来定义字节,DW定义字,DD定义双字,DQ定义4个字,
32、DT定义10个字。这些伪指令的格式及用法见前述。第6章 汇编语言程序设计 4.定义存储单元类型的伪指令定义存储单元类型的伪指令BYTE、WORD、DWORD 定义存储单元的伪指令并不是单独使用,而是和指令结合起来使用的。利用这些伪指令,对存储单元类型进行规定。例如:MOV BYTE PTR DI,00 MOV WORD PTR 1000,00 INC BYTE PTR DI JMP DWORD PTR 2000 第6章 汇编语言程序设计 5.LABEL 本条伪指令用于定义标号名称和属性,它和下一条指令共享存储器单元。格式:名字 LABEL 类型例如:BYTE-ARRAY LABEL BYTE
33、WORD-ARRAY DW 100 DUP(?)在第二条语句中指明了有100个字存储单元,它们的符号地址名为WORD-ARRAY,但在第一行说明这100个字存储单元可以看成200个字节存储单元。符号地址名为BYTE-ARRAY。第6章 汇编语言程序设计 这样,当我们访问存储器操作时,就可以有两种观点:(1)MOV WORD-ARRAY,0 ;是把第一个字置为0。(2)MOV BYTE-ARRAY,0 ;是把第一个字节置为0。利用LABEL伪指令,对存储器单元就可以有不同的划分,这为访问存储器单元提供了较大的灵活性。第6章 汇编语言程序设计 6.SEG和和OFFSET SEG操作符返回存储器地址
34、操作数的段地址部分,而OFFSET返回存储器地址操作数的段内偏移地址部分。例如:NUMBER-1 DD?MOV AX,SEG NUMBER-1 MOV DS,AX ;段地址进入DS。MOV SI,OFFSET NUMBER-1 ;偏移地址进入SI。第6章 汇编语言程序设计 7.TYPE、SIZE和和LENGTH 表表6.3 存储器地址操作数类型值存储器地址操作数类型值 存储器操作数存储器操作数 类型值类型值(DB)字节数据字节数据 1(DW)字数据字数据 2(DD)双字数据双字数据 4(DF)三字数据三字数据 6(DQ)四字数据四字数据 8(DT)五字数据五字数据 10NEAR 指令单元指令单
35、元-1FAR 指令单元指令单元 12第6章 汇编语言程序设计 这里,字节、字等的类型就是它们所占用的字节数,而NEAR和FAR指令单元的类型值没有物理意义。SIZE和LENGTH只应用于存储器地址操作数。LENGTH返回一个你定义的数的尺寸的单元数。SIZE则返回存储器地址操作数占用的字节数。例如:LARGE-NUM DD 40 DUP(0)这里是按双字尺寸分配存储单元的,所以LENGTH(LARGE-NUM)是40,而SIZE(LARGE-NUM)是160。可以看出,如果X是地址操作数,则 SIZE(X)=(LENGTH(X)*(TYPE(X)第6章 汇编语言程序设计 8.段定义伪指令段定义
36、伪指令 (1)SEGMENT/ENDS伪指令。伪指令SEGMENT和ENDS总是成对使用的。用这对伪指令来指定段的名称和范围,还可指明段的定位类型(align type)、组合类型(combine type)和分类名。段定义伪指令的格式为 段名 SEGMENT定位类型组合类型分类名 本段程序内容(指令语句或伪指令语句)段名 ENDS 从SEGMENT伪指令之后出现的指令和伪指令都被认为是在该段之内,直至ENDS出现为止。第6章 汇编语言程序设计 段定义格式中,带有 部分根据需要可有可无。还应指出,当用于定义数据段、附加数据段和堆栈段时,处于SEGMENT/ENDS伪指令中间的语句,只能包括伪指
37、令语句,不能包括指令语句,一般格式为 段名 SEGMENT 数据定义,存储单元分配等伪指令语句 段名 ENDS 当由SEGMENT/ENDS定义代码段时,中间的语句可包括指令语句和与指令有关的伪指令语句。一般格式为 段名 SEGMENT 指令语句和与伪指令有关的伪指令语句 段名 ENDS 第6章 汇编语言程序设计 段定义格式中,各部分的用法说明如下:段名:所定义段的名称。段名是标识符,同一段的SEGMENT/ENDS伪指令前的段名必须一致。一个段一经定义,其中指令的标号、变量等在段内的偏移地址就已排定,它们都在同一个段地址控制之下,整个段占用的存储空间大小也就确定。由SEGMENT/ENDS伪
38、指令所定义的段,通常小于64 K单元,而且经过汇编和连接,定义的各段不互相覆盖。一个源程序模块的典型结构如下:STACK-SEG SEGMENT;STACK-SEG ENDS ;定义堆栈段 第6章 汇编语言程序设计 DATA-SEG SEGMENT;DATA-SEG ENDS ;EXTRA-SEG SEGMENT;EXTRA-SEG ENDS ;CODE-SEG SEGMENT;START:CODE-SEG ENDS ;END START ;源程序模块结束 定义数据段定义附加数据段定义代码(即指令)段第6章 汇编语言程序设计 段定义格式中SEGMENT伪指令后,用 括起来的不是规定的语法符号,
39、而是表示该项是可选的,有时可以全部省略。当它们存在时,用于指明段间的联系形态,说明段定义的辅助属性。现说明如下:定位类型。定位类型给出实际段起点的类型。它有PAGE、PARA、WORD、BYTE四种类型。PAGE:表示相应的段必须从某一页(256个字节)的边界开始。即段的起始地址能为256整除。此时20位的段地址为PAGE=B 第6章 汇编语言程序设计 PARA:表示段的起点是从存储器中的某一个节(一节等于16个字节)的边界开始。也即段的起始地址能被16整除。此时20位的段起始地址为PARA=BWORD:表示段的起点可以从任何一个字的边界(偶地址)开始。即地址能被2整除。段起始地址为WORD=
40、BBYTE:表示段的地址可以从存储器的任何地址开始。段起始地址为BYTE=B对于PAGE和PARA类型其段内的偏移地址都是从0开始的。而对WORD类型,段内偏移地址不一定从0开始,合理选择定位类型,能够使得在进行段和模块的定位连接时,可充分地利用存储器空间。第6章 汇编语言程序设计 组合类型。组合类型在模块式程序设计中表示该段和其它同名段间的组合连接方法。如果在SEGMENT伪指令后面没有指明组合类型,则汇编程序ASM认为这个段是不准备与别的段相连接的。组合类型有以下5种选择:PUBLIC:表示该段可与模块连接时所遇到的其它同名段在满足定位类型的前提下依次连接起来。连接的顺序由连接程序LINK
41、确定。COMMON:表示该段与别的模块中的所有其它同名同类别段共享相同的存储空间。即各段都是从相同的地址开始,具有同样的段地址,且互相覆盖。连接后,段的长度等于最长的COMMON段的长度。第6章 汇编语言程序设计 AT表达式:表示相应段定位在由表达式求值得到的节边界地址上。表达式也可以是一个常数。例如,AT 2345H表示该段定位在实际物理地址23450H处。STACK:与PUBLIC组合类型的处理方式相同,即把不同模块中带有STACK组合类型的同名段连接起来,使这些同名段都从同一基地址开始。但STACK组合方式仅用于堆栈段。MEMORY:表示在连接时,本段应装在被连接的其它段之上,即在同名段
42、中具有最高的地址。若连接时具有MEMORY组合类型的段不止一个,则只有第一段才当成MEMORY组合类型来处理,其它的段将重叠,即按COMMON组合类型来处理。第6章 汇编语言程序设计 类名。类名是程序员任选的一个字符串,使用时必须用单引号括起来类名。连接时,将把不同模块中相同类名的各段在物理地址上相邻的连接在一起,其顺序则与LINK时提供的各模块顺序一致。第6章 汇编语言程序设计 (2)ORG伪指令。伪指令ORG用来规定目标程序存放单元的偏移量。它的格式如下:ORG 表达式其中表达式以65536(216)为模进行计算,计算结果应是一个不为负的常数。若表达式中有标识符,则标识符必须是已经定义过的
43、。汇编程序ASM规定ORG伪指令不能带标识符。例如:START:ORG 2000H是非法语句。第6章 汇编语言程序设计 如果在源程序中的第一条指令用了如下伪指令:ORG 2000H,则汇编程序将把指令指针IP的值置成2000H,目标程序的第一个字节将放置在2000H单元,后面的程序就会依次顺序存放。当遇上另一个ORG语句时,目标程序的存放地址才会从新的ORG语句指定的地址单元存放。例如,若当前的(IP)=2400H,这时若又遇到如下ORG语句:ORG 2464H 则汇编程序会修改IP内容,使(IP)=2464H,并以此存储单元开始存放目标程序。这样就保留了100个字节的存储空间。ORG伪指令可
44、以放置在源程序中的任何位置。第6章 汇编语言程序设计 (3)ASSUME伪指令。ASSUME伪指令语句用来告诉汇编程序在指令执行期间内存的哪一段是数据段,哪一段是堆栈段,哪一段是代码段。ASSUME伪指令语句的格式如下:ASSUME 段寄存器名:段名符,段寄存器名:段名符,上述格式中 内的内容可有可无。例如:ASSUME CS:MYCODE,DS:MYDATA ASSUME ES:MYEXTRA,SS:MYSTACK 第6章 汇编语言程序设计 这两个语句是将所定义的段MYCODE、MYDATA、MYEXTRA和MYSTACK分别置于段寄存器CS、DS、ES和SS的控制之下。ASSUME语句只能
45、安排在代码段内,一般应排在代码段作为首始指令。ASSUME语句中的段寄存器名:段名符可以有一项,也可以有多项,如果一行写不下,可分成两个ASSUME语句。一个源程序模式至少包括一个段,当指令(即代码)、数据及堆栈区都将集中在一个段内时,ASSUME语句的格式应该是为 ASSUME CS:MYCODE,DS:MYCODE,ES:MYCODE,SS:YCODE 第6章 汇编语言程序设计 除了CS以外,各个段寄存器的实际值,还要用MOV指令来赋值。例如:MYCODE SEGMENT ASSUME CS:MYCOED,DS:MYDATA,ES:MYEXTRA,SS:MYSTACK START:MOV
46、AX,MYDATA MOV DS,AX MOV AX,MYEXTRA MOV ES,AX MOV AX,MYSTACK MOV SS,AX MYCODE ENDS 第6章 汇编语言程序设计 9.过程定义伪指令过程定义伪指令PROC,ENDP,NEAR,FAR 在ASM语言中,过程的含义和子程序是一样的。一个过程可以被其它程序所调用,它的最后一条指令总是返回指令,用以控制此过程在执行完毕后,返回到主程序。定义过程的伪指令PROC/ENDP总是成对出现的,在这两条伪指令间的内容就作为一个过程,即一个子程序。有关PROC/ENDP伪指令的格式定义在第4章中已作了介绍,现仅举例说明PROC/ENDP等
47、一组伪指令的用法。下面是实现多字节BCD码相加的完整的程序片段:第6章 汇编语言程序设计 DATA SEGMENT ;定义数据段。FIRST DB 11,22,33,44 ;第一个加数。SECOND DB 55,66,77,88 ;第二个加数。SUM DB 4 DUP(?);存放结果单元。DATA ENDS STACK SEGMENT ;定义堆栈段。STA DB 20 DUP(?);设置堆栈长度为20个字节。TOP EQU LENGTH STA STACK ENDS CODE SEGMENT ;定义代码段。ASSUME CS:CODE,DS:DATA,SS:STACK 第6章 汇编语言程序设计
48、 START:MOV AX,DATA ;装入段寄存器实际值数据。MOV DS,AX MOV AX,STACK ;装入段寄存器实际值堆栈。MOV SS,AX MOV AX,TOP ;设置堆栈指针。MOV SP,AX MOV SI,OFFSET FIRST ;SI指向第一个加数。MOV DI,OFFSET SUM ;DI指向结果单元。MOV BX,OFFSET SECOND ;BX指向第二加数。MOV CX,04 ;共4个字节长。CLD ;清方向标志。CLC ;清进位标志。第6章 汇编语言程序设计 ADITI:CALL AAA ;调用多字节加法子程序。LOOP ADITI ;继续后面主程序。AAA
49、 1 PROC NEAR ;单字节加法子程序。LODSB ;取第一个加数。ADC AL,BX ;相加。DAA ;十进制调整。STOSB ;结果送DI所指单元。INC BX ;修改指针。RET ;返回。AAA ENDP ;子程序结束。CODE ENDS ;程序段结束。END START ;程序结束。第6章 汇编语言程序设计 10.定义结构的伪指令定义结构的伪指令STRUC/ENDS (1)结构的定义。结构伪指令的格式如下:结构名称 STRUC 结构名称 ENDS 如果DB、DW或DD语句包括变量标识符,则该标识符表示一个字段的开始,称为字段标识符。例如,对上述所说的学生学业管理可采用以下所示的结
50、构形式:由DB、DW、DD伪指令所组成的语句序列第6章 汇编语言程序设计 STUDENT-RECORD STRUC NAME DB Li Ping SEX DB 0,0 for male,1 for female AGE DB 25H NUMBER DB?MATH DB 91H PHYSICAL DB 85H CIRCUIT DB 95H STUDENT-RECORD ENDS 第6章 汇编语言程序设计 (2)结构的存储分配和预置。为了给结构分配存储空间或预置,必须有一个援用该结构的语句,其格式如下:变量 结构名称赋值说明其中结构名称是指STRUC伪指令中的结构名称(在前面的例子中为STUDE