《汇编语言的基本语法》由会员分享,可在线阅读,更多相关《汇编语言的基本语法(84页珍藏版)》请在金锄头文库上搜索。
1、汇编语言的基本语法汇编语言的基本语法 1.1. 汇编语言源程序的格式汇编语言源程序的格式DATA SEGMENT AT 2000HARRAY DB a1,a2,a3,a10(a1a10为立即数)为立即数)COUNT EQU $ - ARRAYSUM DW ?DATA ENDSSTACK SEGMENT PARA STACK STACKSTAK DB 10 DUP (?)TOP EQU LENGTH STAKSTACKENDSCODE SEGMENTASSUME CS:CODE, DS:DATA, SS:STACKSTART: MOV AX,DATA MOV DS,AX MOV AX,0 MOV
2、 DI,OFFSET SUM MOV BX,OFFSET ARRAY MOV CX,COUNTLOP: ADD AL,BX ADC AH,0 INC BX LOOP LOP MOV DI,AX MOV AH,4CH INT 21HCODE ENDS END START汇编语言源程序格式的特点是汇编语言源程序格式的特点是: 1 .分段结构分段结构2 .语句行语句行汇编语言程序的语句有两类:汇编语言程序的语句有两类:( 1 ) 指令性语句指令性语句 ( 2 ) 指示性语句指示性语句 汇编语言源程序语句的格式汇编语言源程序语句的格式 汇编语言源程序中的每个语句可以由四项组成,汇编语言源程序中的每个语
3、句可以由四项组成,格式如下:格式如下:名字名字 操作操作 操作数操作数 ;注释注释其中:其中:名字项是指一个标号或变量。名字项是指一个标号或变量。操作项是一个操作码的助记符,它可以是指令、操作项是一个操作码的助记符,它可以是指令、伪指令或宏指令名。伪指令或宏指令名。 操作数项由一个或多个表达式组成,操作数项由一个或多个表达式组成,它提供为执行所要求的操作而需要的信它提供为执行所要求的操作而需要的信息。操作数项可以是常数、寄存器、标息。操作数项可以是常数、寄存器、标号、变量或由表达式组成。号、变量或由表达式组成。注释项用来说明程序或语句的功能。注释项用来说明程序或语句的功能。;为识别注释项的开始
4、。为识别注释项的开始。;也可以也可以从一行的第一个字符开始,此时整行都从一行的第一个字符开始,此时整行都是注释,常用来说明下面一段程序的功是注释,常用来说明下面一段程序的功能。能。 上面四项中带方括号的两项是可选项。上面四项中带方括号的两项是可选项。各项之间必须用各项之间必须用空格空格(space)或或水平水平制表制表(Tab)符隔开。符隔开。(1) 名字项名字项(2) 操作项操作项(3) 操作数项操作数项(4) 注释项注释项(1) 名字项名字项源程序中用下列字符来表示名字:源程序中用下列字符来表示名字:字母字母AZ数字数字09专用字符专用字符 ?、?、 、-、除数字外,所有字符都可以放在源语
5、句的除数字外,所有字符都可以放在源语句的第一个位置。名字中如果用到第一个位置。名字中如果用到则必须是第一则必须是第一个字符。可以用很多字符来说明名字,但只有个字符。可以用很多字符来说明名字,但只有前面的前面的31个字符能被汇编程序所识别。个字符能被汇编程序所识别。 一般说来,名字项可以是标号或变量。一般说来,名字项可以是标号或变量。它它们都用来表示本语句的符号地址们都用来表示本语句的符号地址,都是可有可,都是可有可无的,无的,只有当需要用符号地址来访问该语句时只有当需要用符号地址来访问该语句时它才需要出现。它才需要出现。 标号:标号在代码段中定义,后面跟着标号:标号在代码段中定义,后面跟着冒号
6、:,此外,它还可以作为过程名定义。冒号:,此外,它还可以作为过程名定义。 变量:变量在数据段或附加数据段中定变量:变量在数据段或附加数据段中定义,后面不跟冒号。义,后面不跟冒号。 变量经常在操作数字段出变量经常在操作数字段出现。现。(2)操作项)操作项操作项可以是指令、伪指令或宏指操作项可以是指令、伪指令或宏指令的助记符。对于指令,汇编程序将其令的助记符。对于指令,汇编程序将其翻译为机器语言指令。对于伪指令,汇翻译为机器语言指令。对于伪指令,汇编程序将根据其所要求的功能进行处理。编程序将根据其所要求的功能进行处理。对于宏指令,则将根据其定义展开。对于宏指令,则将根据其定义展开。 (3) 操作数
7、项操作数项 操作数项由一个或多个表达式组成,多个操作数项由一个或多个表达式组成,多个操作数项之间一般用逗号分开。对于指令,操操作数项之间一般用逗号分开。对于指令,操作数项一般给出操作数地址,它们可能有一个,作数项一般给出操作数地址,它们可能有一个,或二个,或三个,或一个也没有。对于伪操作或二个,或三个,或一个也没有。对于伪操作或宏指令,则给出它们所要求的参数。或宏指令,则给出它们所要求的参数。操作数项可以是常数、寄存器、标号、变操作数项可以是常数、寄存器、标号、变量或由表达式组成。量或由表达式组成。 (4) 注释项注释项注释项用来说明一段程序、一条或几条指注释项用来说明一段程序、一条或几条指令
8、的功能。对于汇编语言程序来说,注释项的令的功能。对于汇编语言程序来说,注释项的作用是很明显的,它可以使程序容易被读懂,作用是很明显的,它可以使程序容易被读懂,因此汇编语言程序必须写好注释。注释应该写因此汇编语言程序必须写好注释。注释应该写出本条(或本段)指令在程序中的功能和作用,出本条(或本段)指令在程序中的功能和作用,而不应该只写指令的动作。读者在有机会阅读而不应该只写指令的动作。读者在有机会阅读程序例子时,应注意学习注释的写法,在编制程序例子时,应注意学习注释的写法,在编制程序时,更应学会写好注释。程序时,更应学会写好注释。 指令性语句指令性语句 格式为:格式为: 标号标号 : 操作码操作
9、码 操作数操作数 ; 注释注释 带方括号的为任选项,带方括号的为任选项,标号是指令的符号地址,标号是指令的符号地址,操作码和操作数是用汇编语言指令表示的指令部分操作码和操作数是用汇编语言指令表示的指令部分,注释是对该语句在本程序中的功能的说明。注释是对该语句在本程序中的功能的说明。指示性语句指示性语句格式为:格式为: 名字名字 / 变量变量 命令命令 参数参数 ; 注释注释 命令指示汇编程序进行某种汇编操作命令指示汇编程序进行某种汇编操作,参数是有关的数据,参数是有关的数据,名字是段名、符号名等标识符,变量用变量名表示。名字是段名、符号名等标识符,变量用变量名表示。 常量、标识符和表达式常量、
10、标识符和表达式一、常量一、常量其值在程序中不能改变的量其值在程序中不能改变的量,在汇编语言源程序中的常量有:在汇编语言源程序中的常量有:数字常量、字符常量和符号常量数字常量、字符常量和符号常量( 1 ) 数字常量可以是二进制数、八进制数、十进数字常量可以是二进制数、八进制数、十进制数或十六进制数表示制数或十六进制数表示( 2 ) 字符常量是用单引号字符常量是用单引号 括起来的括起来的ASCII字字符,符, 其值是该字符的其值是该字符的ASCII代码值代码值( 3 ) 符号常量是用标识符定义的常量。符号常量是用标识符定义的常量。例如,采用符号定义语句例如,采用符号定义语句 PORTA EQU 8
11、0H,则指令则指令 MOV AL,PORTA 与指令与指令 MOV AL,80H 等价。等价。二、标识符二、标识符在编程时建立的有特定意义的字符序列,标识符在编程时建立的有特定意义的字符序列,标识符可用作符号常量、名字、变量和标号等。可用作符号常量、名字、变量和标号等。组成标识符有如下规定:组成标识符有如下规定: ( 1 ) 组成标识符的字符有:组成标识符的字符有: 英文大写字母:英文大写字母:AZ; 英文小写字母:英文小写字母: a-z; 数字数字09; 字符字符?、_ 、$;( 2 )字符长度不超过字符长度不超过3l个;个; ( 3 ) 首字符不能是数字;首字符不能是数字; ( 4 ) ?
12、 不能单独作为一个标识符;不能单独作为一个标识符; ( 5 ) 不能把保留字用作标识符,保留字包括助记符、不能把保留字用作标识符,保留字包括助记符、寄存器名等。寄存器名等。三、表达式三、表达式 表达式是常数、标号、变量与一些操作符相表达式是常数、标号、变量与一些操作符相组合的序列,可以有数字表达式和地址表达式组合的序列,可以有数字表达式和地址表达式两种。在汇编期间,汇编程序按照一定的优先两种。在汇编期间,汇编程序按照一定的优先规则对表达式进行计算后可得到一个数值或一规则对表达式进行计算后可得到一个数值或一个地址。个地址。常用的表达式操作符介绍如下:常用的表达式操作符介绍如下: (1) 算术操作
13、符算术操作符 算术操作符有算术操作符有+、-、*、/ 和和MOD。MOD是指除法运算后得到的余数,如是指除法运算后得到的余数,如19/7的商是的商是2,而,而19 MOD 7则为则为5(余数)。(余数)。 算术操作符可以用于数字表达式或地算术操作符可以用于数字表达式或地址表达式中,但当它用于地址表达式时,址表达式中,但当它用于地址表达式时,只有当其结果有明确的物理意义时才是只有当其结果有明确的物理意义时才是有效的结果。例如两个地址相乘或相除有效的结果。例如两个地址相乘或相除是无意义的。在地址表达式中,可以使是无意义的。在地址表达式中,可以使用用 + 或或 - ,但也必须注意其物理意义。,但也必
14、须注意其物理意义。 例如把两个不同段的地址相加也是无意义的。例如把两个不同段的地址相加也是无意义的。经常使用的是地址经常使用的是地址 数字量,它是有意义的。例如数字量,它是有意义的。例如SUM +1是指是指SUM字节单元的下一个字节单元的地址字节单元的下一个字节单元的地址(注意:不是指(注意:不是指SUM单元的内容加单元的内容加1),而),而SUM-1则则是指是指SUM字节单元的前一个字节单元的地址。字节单元的前一个字节单元的地址。例:例: 如果要求把首地址为如果要求把首地址为BLOCK的字数组的第的字数组的第6个字传送到个字传送到DX寄存器,可用指令如下:寄存器,可用指令如下:MOV DX,
15、 BLOCK+ (6-1) * 2 例:例: 如数组如数组ARRAY定义如下,写出把数组长定义如下,写出把数组长度(字数)存入度(字数)存入CX寄存器的指令。寄存器的指令。ARRAY DW 1, 2, 3, 4, 5, 6, 7ARYENDDW ?其中其中ARYEND是为计算数组长度而建立的符号是为计算数组长度而建立的符号地址,所需指令如下:地址,所需指令如下:MOV CX, (ARYEND-ARRAY)/2汇编程序在汇编期间将计算出表达式的值而形汇编程序在汇编期间将计算出表达式的值而形成指令:成指令:MOV CX, 7 (2) 逻辑操作符逻辑操作符 逻辑操作符有:逻辑操作符有:AND(与)、
16、与)、OR(或)、或)、XOR(异或)、异或)、NOT(非)。非)。逻辑操作符都是按位操作的,只能用于数字表逻辑操作符都是按位操作的,只能用于数字表达式中。逻辑操作符要求达式中。逻辑操作符要求汇编程序对其前后两个操汇编程序对其前后两个操作数(或表达式)作指定的逻辑操作作数(或表达式)作指定的逻辑操作。 例:例:OUT PORT_VAL AND 0FEH, AL上例中上例中PORT_VAL为端口号,为端口号,OUT指令中的表达式说明只为偶数号端口输指令中的表达式说明只为偶数号端口输出数据。出数据。 (3) 关系操作符关系操作符关系操作符有:关系操作符有:EQ(相等)、相等)、NE(不等)不等)、
17、LT(小于)、小于)、GT(大于)、大于)、LE(小于或等小于或等于)、于)、GE(大于或等于)。大于或等于)。关系操作符的两个操作数必须都是数字或关系操作符的两个操作数必须都是数字或是同一段内的两个存储器地址。计算的结果应是同一段内的两个存储器地址。计算的结果应为逻辑值:结果为真,表示为为逻辑值:结果为真,表示为0FFFFH;结果结果为假,则表示为为假,则表示为0。 例如:例如:MOV BX,(PORT_VAL LT 5) AND 20) OR (PORT_VAL GE 5) AND 30)则当则当PORT_VAL 5时,汇编结果应该是:时,汇编结果应该是:MOV BX, 20否则,汇编结果
18、应该是:否则,汇编结果应该是:MOV BX, 30 (4) 数值回送操作符数值回送操作符 数值回送操作符有:数值回送操作符有:TYPE、LENGTH、SIZE、OFFSET、SEG等。等。数值回送操作符把一些特征或存储数值回送操作符把一些特征或存储器地址的一部分作为数值回送。器地址的一部分作为数值回送。 TYPE格式为:格式为:TYPE 表达式表达式如果表达式是变量,则汇编程序将如果表达式是变量,则汇编程序将回送该变量的以字节数表示的类型:回送该变量的以字节数表示的类型:DB为为1,DW为为2,DD为为4,DF为为6,DQ为为8,DT为为10。如果表达式是标号,则汇编。如果表达式是标号,则汇编
19、程序将回送代表该标号类型的数值:程序将回送代表该标号类型的数值:NEAR为为 -1,FAR为为 -2。如果表达式为。如果表达式为常数,则应回送常数,则应回送0。 举例:举例:ARRAY DW 1, 2, 3则对于指令则对于指令ADD SI, TYPE ARRAY汇编程序将其形成为:汇编程序将其形成为:ADD SI, 2 LENGTH格式为:格式为:LENGTH 变量变量对于变量中使用对于变量中使用DUP的情况,汇编的情况,汇编程序将回送分配给该变量的单元数,而程序将回送分配给该变量的单元数,而对于其他情况则送对于其他情况则送1。 举例举例1:FEES DW 100 DUP (0)对于指令对于指
20、令MOV CX, LENGTH FEES 汇编程序将使其形成为:汇编程序将使其形成为:MOV CX, 100举例举例2:ARRAY DW 1, 2, 3对于指令对于指令MOV CX, LENGTH ARRAY 汇编程序将使其形成为:汇编程序将使其形成为:MOV CX, 1举例举例3:TABLE DB ABCD对于指令对于指令MOV CX, LENGTH TABLE汇编程序将使其形成为:汇编程序将使其形成为:MOV CX, 1 SIZE格式为:格式为:SIZE 变量变量汇编程序应回送分配给该变量的字汇编程序应回送分配给该变量的字节数。但是,此值是节数。但是,此值是LENGTH值和值和TYPE值的
21、乘积。值的乘积。 例如:例如: MOV CX, SIZE FEES将形成为将形成为 MOV CX, 200又例如:又例如: MOV CX, SIZE ARRAY将形成为将形成为 MOV CX, 2又例如:又例如: MOV CX, SIZE TABLE将形成为将形成为 MOV CX, 1。 OFFSET格式为:格式为:OFFSET 变量或标号变量或标号汇编程序将回送变量或标号的偏移地址值。汇编程序将回送变量或标号的偏移地址值。举例:举例:MOV BX, OFFSET OPER_ONE汇编程序将汇编程序将OPER_ONE的偏移地址作为的偏移地址作为立即数回送给指令,而在执行时则将该偏移地立即数回送
22、给指令,而在执行时则将该偏移地址装入址装入BX寄存器中。所以这条指令的功能与指寄存器中。所以这条指令的功能与指令令LEA BX, OPER_ONE是等价的。是等价的。 SEG格式为:格式为:SEG 变量或标号变量或标号汇编程序将回送变量或标号的段地址值。汇编程序将回送变量或标号的段地址值。举例:如果举例:如果DATA_SEG是从存储器的是从存储器的05000H地址开地址开始的一个数据段的段名,始的一个数据段的段名,OPER1是该段中的一个变是该段中的一个变量名,则量名,则MOV BX, SEG OPER1将把将把0500H作为立即数插入指令。实际上,由作为立即数插入指令。实际上,由于段地址是由
23、连接程序分配的,所以该立即数是连于段地址是由连接程序分配的,所以该立即数是连接时插入的。执行期间则使接时插入的。执行期间则使BX寄存器的内容成为寄存器的内容成为0500H。 PTR格式为:类型格式为:类型 PTR 符号地址符号地址PTR用来给已分配的存储地址(用用来给已分配的存储地址(用符号地址表示)赋予另一种属性,使该符号地址表示)赋予另一种属性,使该地址具有另一种类型。地址具有另一种类型。类型可有类型可有BYTE、WORD、DWORD、FWORD、QWORD、TBYTE、NEAR和和FAR等几种,所以等几种,所以PTR也可以用来建立字、双字、四字或也可以用来建立字、双字、四字或段内及段间的
24、指令单元等。段内及段间的指令单元等。 举例:已有数据定义如下:举例:已有数据定义如下:TWO_BYTE DW ?可以用以下语句对这两个字节赋予另一种可以用以下语句对这两个字节赋予另一种类型定义:类型定义: ONE_BYTE EQU BYTE PTR TWO_BYTE这里这里ONE_BYTE和和TWO_BYTE两个符号两个符号地址具有相同的段地址和偏移地址,但是它们地址具有相同的段地址和偏移地址,但是它们的类型属性不同,前者为的类型属性不同,前者为1,后者为,后者为2。 此外,有时指令要求使用此外,有时指令要求使用PTR操作符。例操作符。例如用如用 MOV BX, 5指令把立即数存入指令把立即数
25、存入BX寄存器内容指寄存器内容指定的存储单元中,但汇编程序不能分清定的存储单元中,但汇编程序不能分清是存入字单元还是字节单元,此时必须是存入字单元还是字节单元,此时必须用用PTR操作符来说明属性,应该写明:操作符来说明属性,应该写明: MOV BYTE PTR BX,5 或或 MOV WORD PTR BX,5 段操作符段操作符段操作符用来表示一个标量、变量段操作符用来表示一个标量、变量或地址表达式的段属性。或地址表达式的段属性。格式为:格式为: 段寄存器段寄存器 地址表达式地址表达式段名段名 地址表达式地址表达式例如,用段前缀指定某段的地址操作例如,用段前缀指定某段的地址操作数数MOV AX
26、,ES:BX + SI SHORT用来修饰用来修饰JMP指令中转向地址的属性,指指令中转向地址的属性,指出转向地址是在下一条指令地址的出转向地址是在下一条指令地址的127个字节个字节范围之内。范围之内。例如:例如: JMP SHORT TAG ;转移属性为短转转移属性为短转移移 . TAG: MOV. THIS格式为:格式为: THIS 属性或类型属性或类型THIS可以象可以象PTR一样建立一个指定一样建立一个指定类型(类型(BYTE、WORD、DWORD)或或指定距离(指定距离(NEAR或或FAR)的地址操作数。的地址操作数。该操作数的段地址和偏移地址与下一个该操作数的段地址和偏移地址与下一
27、个存储单元地址相同存储单元地址相同。 例如:例如: FIRST_TYPE EQU THIS BYTE WORD_TABLE DW 100 DUP (?)此时此时FIRST_TYPE的偏移地址和的偏移地址和WORD_TABLE完全相同,但它是字节类型的;而完全相同,但它是字节类型的;而WORD_TABLE则则是字类型的。是字类型的。又如:又如: START EQU THIS FAR MOV CX, 100这样,这样,MOV指令有一个指令有一个FAR属性的符号地址属性的符号地址START,这就允许其他段的这就允许其他段的JMP指令直接跳转到指令直接跳转到START来。来。 HIGH和和LOW称为字
28、节分离操作符,它接收一个数或地称为字节分离操作符,它接收一个数或地址表达式,址表达式,HIGH取其高位字节,取其高位字节,LOW取其低取其低位字节。位字节。例如:例如:CONST EQU 0ABCDH则则MOV AH, HIGH CONST将汇编成将汇编成 MOV AH, 0ABH指令指令 MOV AH, LOW CONST将汇编成将汇编成 MOV AH, 0CDH 操作符的优先级操作符的优先级我们知道表达式是常数、寄存器、我们知道表达式是常数、寄存器、标号、变量和操作符的组合,在计算表标号、变量和操作符的组合,在计算表达式时,应该首先计算优先级高的操作达式时,应该首先计算优先级高的操作符,然
29、后从左到右地对优先级相同的操符,然后从左到右地对优先级相同的操作符进行计算。括号也可以改变计算次作符进行计算。括号也可以改变计算次序,括号内的表达式应优先计算。序,括号内的表达式应优先计算。表达式中的运算符 高优先级 低1括号中的项,即()和2LENGTH,SIZE,WIDTH,MASK3PTR,OFFSET,SEG,TYPE,THIS4,/,MOD5+,-6EQ,NE,L,LE,GT,GE7NOT8AND9OR,XOR伪指令(伪指令(指示性语句)指示性语句) 伪指令又称为伪操作,它是在对源伪指令又称为伪操作,它是在对源程序汇编期间由汇编程序处理的操作,程序汇编期间由汇编程序处理的操作,它们可
30、以完成如它们可以完成如 定义数据、分配存储区、定义数据、分配存储区、指示程序结束等功能。指示程序结束等功能。 宏指令是由用户按照宏定义格式编宏指令是由用户按照宏定义格式编写的一段程序,其中语句可以是指令、写的一段程序,其中语句可以是指令、伪指令,甚至是已定义的宏指令。伪指令,甚至是已定义的宏指令。 伪指令和指令的区别在于,每一条指令伪指令和指令的区别在于,每一条指令必须生成机器代码,然后在程序运行期间由必须生成机器代码,然后在程序运行期间由CPU来执行其操作;而伪指令是在汇编期间来执行其操作;而伪指令是在汇编期间由汇编程序执行的操作命令,除了数据定义由汇编程序执行的操作命令,除了数据定义及存储
31、器分配伪指令分配存储器空间外,其及存储器分配伪指令分配存储器空间外,其它伪指令不生成目标码。和各种指令一样,它伪指令不生成目标码。和各种指令一样,伪指令也是程序设计不可缺少的工具。下面伪指令也是程序设计不可缺少的工具。下面介绍一些常用的伪指令。介绍一些常用的伪指令。 段定义伪指令段定义伪指令段定义伪指令是表示一个段开始和结束段定义伪指令是表示一个段开始和结束的命令的命令 。 段名段名 SEGMENT段名段名 ENDS 段名由用户命名。对于数据段、附加段和段名由用户命名。对于数据段、附加段和堆栈段来说,段内一般是存储单元的定义、分堆栈段来说,段内一般是存储单元的定义、分配等伪指令语句;对于代码段
32、中则主要是指令配等伪指令语句;对于代码段中则主要是指令及伪指令语句。及伪指令语句。定义了段还必须说明哪个段是代码段,哪定义了段还必须说明哪个段是代码段,哪个段是数据段。个段是数据段。ASSUME伪指令就是建立段和伪指令就是建立段和段寄存器关系的伪指令,其格式为:段寄存器关系的伪指令,其格式为:ASSUME 段寄存器名段寄存器名: 段名,段名,段寄存器名必须是段寄存器名必须是CS、DS、ES和和SS中的中的一个,而段名必须是由一个,而段名必须是由SEGMENT定义的段名。定义的段名。 例例; * * * * * * * * * * * * * * * * * * * * * * *data_se
33、g1 segment ; 定义数据段定义数据段 data_seg1 ends; * * * * * * * * * * * * * * * * * * * * * * * data_seg2 segment ; 定义附加段定义附加段data_seg2 ends; * * * * * * * * * * * * * * * * * * * * * * *code_seg segment ; 定义代码段定义代码段assume cs:code_seg, ds:data_seg1, es:data_seg2start: ; 程序执行的起始地址程序执行的起始地址; set DS register to
34、current data segmentmov ax, data_seg1 ; 数据段地址数据段地址 mov ds, ax ; 存入存入DS寄存器寄存器; set ES register to current extra segmentmov ax, data_seg2 ; 附加段地址附加段地址mov es, ax ; 存入存入ES寄存器寄存器. code_seg ends ; 代码段结束代码段结束; * * * * * * * * * * * * * * * * * * * * * * * * * * end start 由于由于ASSUME伪指令只是指定某个段分配伪指令只是指定某个段分配给
35、哪一个段寄存器,它并不能把段地址装入段给哪一个段寄存器,它并不能把段地址装入段寄存器中,所以在代码段中,还必须把段地址寄存器中,所以在代码段中,还必须把段地址装入相应的段寄存器中:装入相应的段寄存器中:MOV AX,DATA_SEG1 ; 数据段地址数据段地址MOV DS,AX ; 存存入入DS寄存器寄存器MOV AX,DATA_SEG2 ; 附加段地址附加段地址MOV ES,AX ; 存存入入ES寄存器寄存器 如果程序中还定义了堆栈段如果程序中还定义了堆栈段STACK_SEG,也需,也需要把段地址装入要把段地址装入SS中:中:MOV AX,STACK_SEG ; 堆栈段地址堆栈段地址MOV
36、SS,AX ; 存存入入ES寄存器寄存器 注意,在程序中不需要用指令装入代码段注意,在程序中不需要用指令装入代码段的段地址,因为在程序初始化时,装入程序已的段地址,因为在程序初始化时,装入程序已将代码段的段地址装入将代码段的段地址装入CS寄存器了。寄存器了。程序开始和结束伪指令程序开始和结束伪指令在程序的开始可以用在程序的开始可以用NAME或或TITLE作为模块的名字,其格式为:作为模块的名字,其格式为:NAME 模块名模块名TITLE 文件名文件名表示源程序结束的伪指令的格式为:表示源程序结束的伪指令的格式为:END 标号标号 注意:注意:NAME及及TITLE伪指令并不是必伪指令并不是必需
37、的,如果程序中既无需的,如果程序中既无NAME又无又无TITLE伪伪指令,则将用源文件名作为模块名。指令,则将用源文件名作为模块名。 END伪指令中的伪指令中的“标号标号”指示程序开始指示程序开始执行的起始地址。如果多个程序模块相连接,执行的起始地址。如果多个程序模块相连接,则只有主程序的则只有主程序的END要加上标号,其他子程要加上标号,其他子程序模块则只用序模块则只用END而不必指定标号。上例最而不必指定标号。上例最后使用了后使用了END START伪指令。汇编程序将在伪指令。汇编程序将在遇遇END时结束汇编,并且程序在运行时从时结束汇编,并且程序在运行时从START开始执行。开始执行。
38、数据定义及存储器分配伪指令数据定义及存储器分配伪指令 8086提供了各种数据及存储器分配伪指令,提供了各种数据及存储器分配伪指令,这些伪指令在汇编程序对源程序进行汇编期间,这些伪指令在汇编程序对源程序进行汇编期间,由汇编程序完成数据类型定义及存由汇编程序完成数据类型定义及存 储器分配等储器分配等功能。功能。 数据定义及存储器分配伪指令的格式是:数据定义及存储器分配伪指令的格式是: 变量变量 助记符助记符 操作数操作数, ,操作数操作数 ;注释注释 数据定义及存储器分配伪指令格式中的数据定义及存储器分配伪指令格式中的变量变量是操作数的符号地址,它是可有可无的,是操作数的符号地址,它是可有可无的,
39、它的作用与指令语句前的标号相同,区别是变它的作用与指令语句前的标号相同,区别是变量后面不加冒号。如果语句中有变量,那么汇量后面不加冒号。如果语句中有变量,那么汇编程序将操作数的第一个字节的偏移地址赋于编程序将操作数的第一个字节的偏移地址赋于这个变量。这个变量。注释注释字段用来说明该伪指令的功能,它字段用来说明该伪指令的功能,它也不是必须有的。也不是必须有的。助记符助记符字段说明所用伪指令的助记符。字段说明所用伪指令的助记符。 下面介绍常用的数据定义伪指令。下面介绍常用的数据定义伪指令。DB(define byte)DB伪指令用来定义字节,对其后的每个数据都伪指令用来定义字节,对其后的每个数据都
40、存储在一个字节中。存储在一个字节中。DB能定义十进制数、二进制数、能定义十进制数、二进制数、十六进制数和十六进制数和ASCII字符,二进制数和十六进制数字符,二进制数和十六进制数要分别用要分别用B和和H表示,表示,ASCII字符用单引号(字符用单引号( )括起来。)括起来。DB还是唯一能定义字符串的伪操作,还是唯一能定义字符串的伪操作,串中的每个字符占用一个字节。串中的每个字符占用一个字节。 请看下面数据定义的例子,注意请看下面数据定义的例子,注意DB定义定义的每个数据的存储情况,左边第一列是汇编的每个数据的存储情况,左边第一列是汇编程序为数据分配的字节地址,第二列是相应程序为数据分配的字节地
41、址,第二列是相应地址中存储的数据或地址中存储的数据或ASCII字符(均用十六进字符(均用十六进制表示)。变量制表示)。变量DATA7定义了定义了3个数据和一个个数据和一个字符串,每个数据或串用字符串,每个数据或串用,分开,它们分别分开,它们分别存储在偏移地址存储在偏移地址002E开始的开始的6个字节单元中。个字节单元中。0000 19 DATA1 DB 25 ; 十进制数十进制数 0001 89 DATA2 DB 10001001B ; 二进制数二进制数0002 12 DATA3 DB 12H ; 十六进制数十六进制数0010 ORG0010H ; 指定偏移地址为指定偏移地址为10h0010
42、32 35 39 31 DATA4 DB 2591 ; ASCII码数码数0018 ORG0018H ; 指定偏移地址为指定偏移地址为18h0018 00 DATA5 DB ? ; 保留一个字节保留一个字节0020 ORG0020H ; 指定偏移地址为指定偏移地址为20h0020 4D 79 20 6E 61 6DDATA6 DB My name is Joe ; ASCII码字符码字符 65 20 69 73 20 4A 6F 65002E 0A 10 02 31 30 42DATA7 DB 10,10H,10B,10B ; 不同的数据类型不同的数据类型 DW(define word)DW伪
43、指令用来定义字,对其后的每个数伪指令用来定义字,对其后的每个数据分配据分配2个字节(个字节(1个字),数据的低个字),数据的低8位存储位存储在低字节地址中,高在低字节地址中,高8位存储在高字节地址中,位存储在高字节地址中,如下例中的变量如下例中的变量DATA8的数据存储在的数据存储在0070字地字地址中,其中址中,其中0070字节存储字节存储0BAH,0071字节存字节存储储03H。DW还可存储变量或标号的偏移地址。还可存储变量或标号的偏移地址。见下面见下面DW伪指令的例子。伪指令的例子。DD(define doubleword)DD伪指令用来定义双字,对其后的每个伪指令用来定义双字,对其后的
44、每个数据分配数据分配4个字节(个字节(2个字)。该伪指令同样将个字)。该伪指令同样将数据转换为十六进制,并根据低地址存储低字数据转换为十六进制,并根据低地址存储低字节,高地址存储高字节的规则来存放数据。如节,高地址存储高字节的规则来存放数据。如下例下例DATA15的存储情况是:的存储情况是:00A8:0F2H,00A9H:57H,00AAH:2AH,00ABH:5CH。用用DD存入地址时,第一个字为偏移地址,存入地址时,第一个字为偏移地址,第二个字为段地址。第二个字为段地址。 DQ(define quadword)DQ伪指令用来定义伪指令用来定义4字,即字,即64位字长的数据,位字长的数据,D
45、Q之后的每个数据占用之后的每个数据占用8个字节(个字节(4个字)。个字)。DT(define ten bytes)DT伪指令用来为压缩的伪指令用来为压缩的BCD数据分配存储单元,数据分配存储单元,它虽然可以分配它虽然可以分配10个字节(个字节(5个字),但最多只能输个字),但最多只能输入入18个数字,要注意的是,数据后面不需要加个数字,要注意的是,数据后面不需要加“H”。下面是下面是DQ和和DT的例子。的例子。 DUP(duplicate)DUP伪指令可以按照给定的次数来复制某个伪指令可以按照给定的次数来复制某个(某些)操作数,它可以避免多次键入同样一个(某些)操作数,它可以避免多次键入同样一
46、个数据。例如,把数据。例如,把6个个FFH存入相继字节中,可以用存入相继字节中,可以用下面两种方法,显然用下面两种方法,显然用DUP的方法更简便些。的方法更简便些。存入存入6字节的字节的FFHDATA20 DB 0FFH 0FFH 0FFH 0FFH 0FFH 0FFH;DATA21 DB 6 DUP(0FFH) DUP操作一般用来保留数据区,如操作一般用来保留数据区,如用数据定义伪指令用数据定义伪指令DB 64 DUP(?)可保留可保留64个字节单元。个字节单元。DUP还可以嵌套。还可以嵌套。 表达式赋值伪操作表达式赋值伪操作EQU 有时程序中多次出现同一个表达式,为方便起有时程序中多次出现
47、同一个表达式,为方便起见可以用赋植伪操作给表达式赋予一个名字,其格见可以用赋植伪操作给表达式赋予一个名字,其格式如下:式如下: Expresstion_name EQU Expresstion 此后,程序中凡需要用到该表达式之处就可以用此后,程序中凡需要用到该表达式之处就可以用表达式名来代替。上式中表达式可以是任何有效的表达式名来代替。上式中表达式可以是任何有效的操作数格式,可以是任何可以求出常数值的表达式,操作数格式,可以是任何可以求出常数值的表达式,也可以是任何有效的助记符。也可以是任何有效的助记符。 EQU是一个赋值伪操作(伪指令),是一个赋值伪操作(伪指令),它给一个数据标号赋于一个常
48、数值,但它给一个数据标号赋于一个常数值,但这个常数不占用存储单元。当这个数据这个常数不占用存储单元。当这个数据标号出现在程序中时,汇编程序即用它标号出现在程序中时,汇编程序即用它的常数值代替数据标号。的常数值代替数据标号。EQU可以在数可以在数据段之外使用,甚至可用在代码段中间。据段之外使用,甚至可用在代码段中间。 假定在数据段和代码段中要多次使用一个假定在数据段和代码段中要多次使用一个数据(如数据(如25),那么在编程时凡是用到),那么在编程时凡是用到25的地的地方都可用数据标号方都可用数据标号COUNT来表示。如果程序来表示。如果程序想修改这个数据,那么只需修改想修改这个数据,那么只需修改
49、EQU的赋值,的赋值,而无须修改程序中其它部分,如而无须修改程序中其它部分,如COUNTER和和MOV语句就不必修改。语句就不必修改。 COUNT EQU 25 COUNTER DB COUNTMOV AL, COUNT DATA EQU HEIGHT + 12 ; 地址表达式赋以符号地址表达式赋以符号ALPHA EQU 7 ; 常数赋以符号名常数赋以符号名BETA EQU ALPHA-2 ; 把把7-2=5赋以符号名赋以符号名BETAADDR EQU VAR + BETA ; VAR+5赋以符号名赋以符号名ADDRB EQU BP + 8 ; 变址引用赋以符号名变址引用赋以符号名 BP8 E
50、QU DS:BP + 8 ; 加段前缀的变址引用赋以符号名加段前缀的变址引用赋以符号名P8 注意:在注意:在EQU语句的表达式中,如果有变语句的表达式中,如果有变量或标号的表达式,则在该语句前应该量或标号的表达式,则在该语句前应该先给出它们的定义。如上例,先给出它们的定义。如上例,ALPHA必必须在须在BETA之前定义,否则汇编程序将指之前定义,否则汇编程序将指示出错。示出错。= 伪操作伪操作 赋值伪操作赋值伪操作=的作用与的作用与EQU类似。类似。它们之间的区别是,它们之间的区别是,EQU伪操作中的标伪操作中的标号名是不允许重复定义的,而号名是不允许重复定义的,而=伪操作是伪操作是允许重复定
51、义的。允许重复定义的。例如,例如, TMP EQU 5 TMP EQU TMP+1 则是错误语句,因为则是错误语句,因为TMP已赋值为已赋值为5,就不能再把它定义为其它数值。就不能再把它定义为其它数值。而而 TMP = 5 TMP = TMP+1 则是允许使用的,因为则是允许使用的,因为=伪操作允许重伪操作允许重复定义。第一个语句复定义。第一个语句TMP的值为的值为5,第二个,第二个语句语句TMP的值就为的值就为6了。了。地址计数器与对准伪指令地址计数器与对准伪指令 1地址计数器地址计数器在汇编程序对源程序汇编的过程中,使用在汇编程序对源程序汇编的过程中,使用地址计数器来保存当前正在汇编的指令
52、的地址。地址计数器来保存当前正在汇编的指令的地址。地址计数器的值在汇编语言中可用来表示。地址计数器的值在汇编语言中可用来表示。当用在伪指令的参数字段时,它所表示当用在伪指令的参数字段时,它所表示的是地址计数器的当前值的是地址计数器的当前值 汇编语言允许用户直接用来引用地址计汇编语言允许用户直接用来引用地址计数器的值,例如指令:数器的值,例如指令:JMP + 6它的转向地址是它的转向地址是JMP指令的首地址加上指令的首地址加上6。当用在指令中时,它表示本条指令的第一个当用在指令中时,它表示本条指令的第一个字节的地址。在这里,字节的地址。在这里,+ 6必须是另一条指令必须是另一条指令的首地址。否则
53、,汇编程序将指示出错信息。的首地址。否则,汇编程序将指示出错信息。当用在伪指令的参数字段时,则和它用当用在伪指令的参数字段时,则和它用在指令中的情况不同,它所表示的是地址计数在指令中的情况不同,它所表示的是地址计数器的当前值。例如指令:器的当前值。例如指令: ARRAY DW 1, 2, + 4, 3, 4, + 4假设汇编时假设汇编时ARRAY 分配的偏移地址为分配的偏移地址为0074H,则汇编后,则汇编后,+ 4所在的两个字单元:所在的两个字单元: (ARRAY+4)=0078+4=007CH(ARRAY+0A)=007E+4=0082H应当注意,应当注意,ARRAY数组中的两个数组中的两
54、个+ 4得到的得到的结果是不同的,这是由于的值是在不断变化的缘结果是不同的,这是由于的值是在不断变化的缘故。当在指令中用到时,它只代表该指令的首地故。当在指令中用到时,它只代表该指令的首地址,而与本身所在的字节无关。址,而与本身所在的字节无关。2EVEN伪指令伪指令EVEN伪指令使下一个变量或指令开始于偶数伪指令使下一个变量或指令开始于偶数字节地址。字节地址。例如:例如:DATA_SEG SEGMENT BYTE_DAT DB ?EVENWORD_DAT DW 100 DUP (?)DATA_SEG ENDS一个字的地址最好从偶地址开始,所以对于字一个字的地址最好从偶地址开始,所以对于字数组为
55、了保证它从偶地址开始,可以在数组为了保证它从偶地址开始,可以在DW定义之定义之前用前用EVEN伪指令来达到这一目的。伪指令来达到这一目的。3 ALIGN伪指令伪指令 ALIGN伪指令使它后面的数据或指令从伪指令使它后面的数据或指令从2的整数倍地址的整数倍地址开始。其格式为:开始。其格式为: ALIGN 2n (n为任意整数为任意整数)例如:例如: ALIGN 4 ARRAY DD 100 DUP (?)ALIGN伪指令保证了双字数组伪指令保证了双字数组ARRAY地址边界从地址边界从4的倍数的倍数开始。开始。 ALIGN伪指令是将当前偏移地址指针指向伪指令是将当前偏移地址指针指向2的乘方的整数的
56、乘方的整数倍的地址,如果源地址指针以指向倍的地址,如果源地址指针以指向2的乘方的整数倍的地址,的乘方的整数倍的地址,则不作调整;否则将指针加以一个数,使地址指针指向下一则不作调整;否则将指针加以一个数,使地址指针指向下一个个2的乘方的整数倍的地址。的乘方的整数倍的地址。当然,当然,ALIGN 2和和EVEN是等价的。是等价的。基数控制伪指令基数控制伪指令 .RADIX伪指令伪指令.RADIX可以把默认的基数改变为可以把默认的基数改变为216范围范围内的任何基数。其格式如下:内的任何基数。其格式如下:.RADIX 基数值基数值其中基数值用十进制数来表示。其中基数值用十进制数来表示。 例如:例如:
57、MOV BX, 0FFH ;16进制数标记为进制数标记为HMOV BL, 10000101B ;二进制数标记为二进制数标记为BMOV BX, 178 ;10进制为默认的基数,可无标进制为默认的基数,可无标记记.RADIX16 ;以下程序默认以下程序默认16进制数进制数 MOV BX, 0FF ;16进制为默认的基数,可无标记进制为默认的基数,可无标记 MOV BX, 178D ;10进制数应加标记进制数应加标记D应当注意,在用应当注意,在用 .RADIX 16把基数定为十六进制后,十把基数定为十六进制后,十进制数后面都应跟字母进制数后面都应跟字母D。在这种情况下,如果某个十六进在这种情况下,如果某个十六进制数的末字符为制数的末字符为D,则应在其后跟字母则应在其后跟字母H,以免与十进制数以免与十进制数发生混淆。发生混淆。