当前位置:文档之家› 指令系统及汇编语言程序设计

指令系统及汇编语言程序设计

指令系统及汇编语言程序设计2.4 伪指令伪指令本身不会产生可执行的机器指令代码,它仅仅是告诉汇编程序有关源程序的某些信息,或者用来说明内存单元的用途。

伪指令在汇编过程中由汇编程序进行处理。

2.4.1 数据定义伪指令数据定义伪指令用于定义变量的类型、给存储器赋初值或给变量分配存储单元。

常用的数据定义伪指令有DB、DW和DD等。

格式: [变量名] 伪指令助记符数据表项功能:定义一个数据存储区,其类型由所定义的数据定义指令而指定。

操作说明:方括号中的变量名为任选项,变量名后面不跟冒号“:”。

数据表项可以包含多个数据之间用逗号分隔开。

数据定义伪指令助记符有以下三种:(1) DB定义变量类型为字节(BYTE),DB后面的每个数据占一个字节。

(2) DW 定义变量类型为字(WORD),DW后面的每个数据占一个字,即两个字节。

在内存中,低字节在前,高字节在后。

(3) DD 定义变量类型为双字(DWORD),后面的每个数据占两个字。

在内存中,低位字在前,高位字在后。

例如,有下列数据定义语句D1 DB 1,-12D2 DW 1,2010HD3 DD 1,10203040H数据表项中除了常数、表达式和字符串外,还可以是问号“?”,它仅给变量保留相应的存储单元,而不给变量赋初值。

相同的操作数重复出现时,可用重复符号“DUP”表示。

其格式为:n DUP(初值[,初值,……]);n表示重复的次数,圆括号中为重复的内容。

下面是用问号或DUP表示操作数的例子:ARRAY DB 1000 DUP(0)VAR DW ?,?2.4.2 符号定义伪指令1. 赋值伪指令格式:变量名 EOU 表达式功能:将右边表达式的值赋给左边的变量。

操作说明:表达式可以是一个常数、符号、数值表达式或地址表达式。

需要注意的是:EQU伪指令不允许对同一符号重复定义。

EQU伪指令具体应用举例如下:CR EQU ODH ;定义CR为常数(回车的ASCII代码)TAB EQU TABLE-ASCII ;定义变量DIS EQU 1024*768 ;定义数值表达式ADR EQU ES:[DI+3] ;定义地址表达式M EQU MOV ;定义助记符2.等号(=)伪指令格式:变量名=表达式功能:将右边表达式的值赋给左边的变量。

操作说明:等号(=)伪指令的功能与EQU伪指令相仿,它可以对同一个名字重复定义。

利用等号(=)伪指令可以使程序设计更加灵活。

例如下面的程序段:TABLE=1MOV AX,TABLERRRR:ADD AX,1┊TABLE=TABLE+1MOV AX,TABLECMP AX,100JNE RRRR┊3. 定义符号名伪指令LABEL格式:符号名 LABEL 类型功能:定义一个标号或变量名,并指定其类型。

操作说明:其中符号名可以是标号或变量,LABEL伪指令通常要与指令语句或DB、DW、DD伪指令语句连用。

与指令连用时,类型属性有NEAR和FAR两种;与DB等伪指令语句连用,可以使同一个数据区既有BYTE属性,又有WORD属性和DWORD属性,这样在以后的程序中根据不同的需要分别以字节或字为单位存取其中的数据。

LABEL伪指令具体使用如下:DATAW LABEL WORD ;变量DATAW类型为WORDDATAB DB 20 DUP(?) ;变量DATAB类型为BYTEMOV DATAW,AX ;按字存入MOV DATAB[2],AL ;按字节存入LABEL伪指令也可以将属性已经定义为NEAR的标号再定义为FAR属性。

例如:ABCF LABEL FAR ;过程入口(远程调用)ABC MOV AX,0000H ;过程入口(段内调用)上面的过程既可用标号ABC在本段调用,也可以用标号ABCF被其他段调用。

2.4.3 段定义伪指令段定义伪指令在汇编语言源程序中定义逻辑段。

常用的段定义伪指令有ASSUME、SEGMENT和ENDS等。

1. 段定义伪指令SEGMENT和ENDSSEGMENT和ENDS伪指令用于定义一个逻辑段,给逻辑段赋予—个段名,并在后面的任选项中给出这个逻辑段的其他特性,如定位类型、组合类型和类别。

段定义伪指令格式如下:段名SEGMENT [定位类型][组合类型][‘类别’]┊段名 ENDS说明: SEGMENT伪指令定义一个逻辑段的开始,ENDS伪指令则表示一个逻辑段的结束,这两个伪指令总是成对出现,而且前面的段名必须一致。

两个伪指令语句之间的部分是该逻辑段的内容。

汇编语言的逻辑段包括代码段、数据段和堆栈段等。

代码段主要是程序指令和某些伪指令;数据段用于定义数据和存储单元;堆栈段为堆栈操作预留出存储空间。

SEGMENT伪指令后面可以有三个任选项:1)定位类型定位类型任选项是告诉汇编程序如何确定逻辑段的边界在存储器中的位置,定位类型有四种:① BYTE表示逻辑段边界可以从任何一个字节开始。

② WORD 表示逻辑段边界从字地址开始,这样该逻辑段的起始地址必须是偶数。

③ PARA 表示逻辑段边界从节地址开始,16个字节称为一个节。

如果省略定位类型任选项,汇编语言程序默认该逻辑段为PARA。

④ PAGE表示逻辑段边界地址从页边界开始,256个字节称为一个页。

2)组合类型 SEGMENT伪指令的第二个任选项是组合类型,它告诉连接程序,装入存储器时各个逻辑段如何进行组合。

组合类型有6种。

① NONE 此项为不组合,如果编程时省略SEGMENT伪指令的组合类型。

② PUBLIC 汇编程序连接时,将不同程序模块中具有相同的类别名的逻辑段顺序连接成一个逻辑段装入内存。

③ STACK 组合类型为STACK时,编译程序把所有同名段连接成一个连续的堆栈段。

④ COMMON该组合类型产生一个覆盖段。

模块连接时,如果有相同的类别名,则都从同一个地址开始装入,因而连接的逻辑段将发生重叠。

连接以后段的长度等于原来最长的逻辑段的长度,重叠部分的内容是最后一个逻辑段的内容。

⑤ MEMORY组合类型为MEMORY时,表示本段在存储器中应定位在所有其他段的最高地址。

⑥ AT AT组合类型表示本段可以定位在表达式所指示的边界上。

如:AT 0830H ;本段的地址从0830H开始。

3)类别名类别名必须用单引号括起来,类别名可由程序设计人员自己选定任何字符串组成,但它不能再作为程序的标号,变量名或其他定义的符号。

在连接处理时,LINK程序把类别名相同的所有段存放在连续的存储区内。

下面是一个分段结构的源程序框架:DATAl SEGMENT┊DATAl ENDSSTACK1 SEGMENT PARA STACK┊STACK1 ENDSCODE SEGMENTASSUME CS:CODE,DS:DATAl,SS:STACKlBEGIN:……┊CODE ENDSEND BEGIN2. 指定段址伪指令ASSUME格式:ASSUME 段寄存器名:段名[,段寄存器名:段名,……]功能:指定段寄存器与某个逻辑段建立对应关系。

操作说明:其中段寄存器名是指四个段寄存器CS、SS、DS、ES中的一个,段名是指逻辑段的段名。

需要注意的是:ASSUME伪指令只是告诉汇编程序段寄存器与逻辑段的关系,并没有给段寄存器赋予实际的初值。

若要给段寄存器赋值,可参考下面程序:CODE SEGMENTASSUME CS:CODE,DS:DATA1,SS:STACKlMOV AX,DATA1MOV DS,AXMOV AX,STACKlMOV SS,AX┊CODE ENDS2.4.4 过程定义伪指令程序设计中,我们常常把具有一定功能的程序段设计成一个子程序。

汇编程序用“过程”来构造子程序。

格式:过程名 PROC [NEAR/FAR] ;NEAR与FAR只选一个,或都不选┊RET过程名 ENDP功能:定义一个过程(子程序)。

操作说明:其中,过程名不能省略,过程的开始和结束应使用同一个过程名。

过程名也就是子程序的程序名,可以通过CALI指令调用,它类同于一个标号的作用,具有三个属性:段、偏移量和类型。

类型可以选择NEAR或FAR,如果没有选择距离类型,则默认为NEAR。

2.4.5 定位伪指令ORG和当前位置计数器$格式:ORG 数值表达式功能:指定在它之后的程序段或数据块所存放的单元起始地址的偏移量。

当前地址计数器‘$’它表示当前地址,即地址计数器的值。

例如:DATA SEGMENTORG 20HD1 DB 12H,13HORG $+01HD2 DB 61H,62H,63HDATA ENDSCODE SEGMENTASSUME CS:CODE,……ORG 100HBEGIN: MOV AX,DATA┋CODE ENDS上面的数据段中,D1的段内偏移量为0020H而不是0000H,D2的段内偏移量是0023H。

代码段里,指令代码从偏移量0100H处开始。

2.4.6 结束汇编指令END格式: END 标号功能:通知汇编程序结束汇编。

操作说明:标号为主程序执行时的入口标号。

注意,该指令并表示执行程序结束,只是汇编程序结束汇编。

而要计算机停止执行程序而退回到DOS操作系统,需用DOS调用:MOV AH,4CHINT 21H第2章指令系统及汇编语言程序设计2.5 汇编语言程序设计2.5.1 汇编语言程序1. 汇编语言的基本概念使用助记符号来表示二进制格式的指令代码和变量地址的指令称为符号指令。

汇编语言程序运行之前要将其转换成机器代码,转换的过程是由编译程序完成。

2. 汇编语言源程序的格式汇编语言源程序采用分段式结构,一个汇编语言源程序由若干个逻辑段组成,每个逻辑段以SEGMENT语句开始,以ENDS语句结束,整个源程序以END语句结束(表示结束汇编)。

下面给出一个简单的汇编语言源程序。

DATA SEGMENT ;定义一个名字为DATA的段DAT DB 1,2,0 ;在DATA段内定义3字节数据DATA ENDS ;DATA段结束;---------------------------------------------------------STACK SEGMENT PARA STACK ;定义名字为STACK的堆栈段DW 20 DUP(0) ;堆栈段大小为20个字STACK ENDS ;堆栈段结束;---------------------------------------------------------CODE SEGMENT ;定义一个名为CODE的程序代码段ASSUME CS:CODE,DS:DATA,SS:STACKBEGIN: MOV AX,DATAMOV DS,AX ;给DS赋数据段初值MOV AL,DATADD AL,DAT+1 ;前两个数据相加MOV DAT+2,AL ;和存入第三个数据的位置MOV AH,4CHINT 21H ;使用系统调用返回操作系统CODE ENDS ;代码段结束;----------------------------------------------------------END BEGIN ;源程序结束,入口地址为BEGIN从上面的例子可以看出,汇编语言源程序由若干段组成,最上面是数据段,接下来是堆栈段,最后是代码段。

相关主题