您好,欢迎来电子发烧友网! ,新用户?[免费注册]

当前位置:电子发烧友网 > 图书频道 > 电子 > 《计算机组成原理与汇编语言》 > 第3章 指令系统与汇编语言设计

第10节 汇编语言运算符

 1.定义数据伪指令

   该类伪指令用来定义存贮空间及其所存数据的长度。
   
   DB——定义字节,即每个数据是1个字节。
   DW——定义字,即每个数据占1个字(2个字节)。
   DD——定义双字,即每个数据占2个字。低字部分在低地址,高字部分在高地址。
   DQ——定义4字长,即每个数据占4个字。
   DT——定义10个字节长,用于压缩式十进制数,

   例如:

   DATA1DB5,6,8,100表示从DATA1单元开始,连续存放5,6,8,100,共占4个字节地址。
   DATA2 DW 7,287

表示从DATA2单元开始,连续存放7,287两个字,共占4个字节地址。定义一个存贮区时,也可以不放数据,如:
   TABLE DB?
  
表示在TABLE单元中存放的内容是随机的。当一个定义的存贮区内的每个单元要放置同样的数据时,可用DUP操作符,

     如:

     BUFFER DB 100DUP(0)
   
  表示以BUFFER为首地址的100个字节中存放00H数据。
 
   2. 符号定义伪指令EQU

EQU伪指令给符号定义一个值。在程序中,凡是出现该符号的地方,汇编时均用其值代替,

     如:

   TIMES EQU 50
   DATA DB TIMESDUP(?)

上述两个语句实际等效于如下一条语句:DATA DB 50DUP(?)

   3. 包含伪指令INCLUDE
 
包含伪指令INCLUDE用来在程序中指明包含另一个程序。如果在用户所编写的程序中,某些地方需要这种转换程序,在该处写一条伪指令:

   INCLUDE B:CONVERT.LIB
   
即可。汇编程序在汇编时,一旦遇到该指令,就在B盘上寻找CONVERT.LIB程序,找到后就将这个程序包含在用户程序中。
   
   4. 段定义伪指令SEGMENT和ENDS

一般来说,一个完整的汇编源程序由3个段组成,即堆栈段、数据段和代码段。段定义伪指令可将源程序划分成若干 段,以便生成目的代码和连接时将各同名段进行组合。

   段定义伪指令一般格式为

   段名SEGMENT[定位类型][组合类型][类别]
    … 段名 ENDS
   SEGMENT和ENDS应成对使用,缺一不可。

   伪指令各部分书写规定如下: 

   ①段名:段名是不可省略的。其他是可选项,是赋予段名的属性,可以省略。段名是给定义的段所起的名称,
    
     例如:

   STACK SEGMENT STACK
   DW 20DUP(?)
   STACK ENDS

   ②定位类型:定位类型表示该段起始地址位于何处,它可以是字节型的(BYTE),即段起始地址可位于任何地方;可以是字型(WORD)的,段起始地址必须
               
             位于偶地址,即地址最后一位是0(二进制的);也可以是节型(PARA)的,即段起始地址必须能被16除尽;也可以是页型的(PAGE),即段起始
               
             地址可被256除尽(一页为256个字节);也可以缺省。缺省时,段起始地址便定位为PARA型的。

   ③组合类型:组合类型用于告诉连接程序,该段和其他段的组合关系。连接程序可以将不同模块的同名段进行组合。根据组合类型,可将各段连接在一起,

             或重叠在一起,

             组合类型有:

             NONE——表明本段与其他段逻辑上不发生关系,当组合类型项省略时,便指定为这一组合类型。
                
             PUBLIC——表明该段与其他模块中用PUBLIC说明的同名段连接成一个逻辑段,运行时装入同一个物理段中,使用同一个段地址。 
                
             STACK——每个程序模块中,必须有一个堆栈段。 
                
             COMMON——表明该段与其他模块中由COMMON说明的所有同名段连接时,被重叠放在一起,其长度是同名段中最长者的长度。 
                
             MEMORY——由MEMORY说明的段。在连接时,它被放在所装载程序的最后存贮区(最高地址)。 

   ④类别:是用单引号括起来的字符串,以表明该段的类别,如代码段(CODE)、数据段(DATA),堆栈段(STACK)等。 

   例如有两个模块: ;

   模块1

   STACK SEGMENT STACK
   DW 200DUP(?)
   STACK ENDS
   DATA SEGMENT COMMON
    …DATA ENDS
   CODE SEGMENT PUBLIC
   …CODE ENDS

   模块2

   STACK SEGMENT STACK
   DW 30DUP(?)
   STACK ENDS
   DATA SEGMENT COMMON
    …DATA ENDS
   CODE SEGMENT PUBLIC
   …CODE ENDS
   END 

 5. 设定段寄存器伪指令ASSUME

  ASSUME——段寄存器定义伪指令。它可通知汇编程序,哪一个段寄存器是该段的段寄存器,以便对使用变量或标号的指令汇编出正确的目的代码,

   其格式为:

   ASSUME段寄存器:段名[,段寄存器:段名,……]

   例如:

   CODE SEGMENT
   ASSUMECS:CODE,DS:DATA,SS:STACK
   MOV AX,DATA
   MOV DS,AX
    …CODE ENDS
 6.定义过程的伪指令PROC和ENDP

  在程序设计中,可将具有一定功能的程序段看成为一个过程(相当于一个子程序)。它可以被别的程序调用(用CALL指令)或由JMP指令转移到此执行;也可以由程序
    
  顺序执行;也可以作为中断处理程序,在中断响应后转此执行。一个过程由伪指令PROC和ENDP来定义,

    其格式为

   过程名 PROC[类型]
    … 过程体
   RET
   过程名 ENDP

   例如 :一个延时100ms的子程序,其过程可定义如下:

   SOFTDLY PROC
   MOV BL,10
   ;内环延时10ms
   DELAY: MOV CX,2801
   WAIT: LOOP WAIT 
   DEC BL
   JNZ DELAY
   RET
   SOFTDLY ENDP

 为了不破坏主程序的工作状态,通常在过程中应保护该过程所用到的通用寄存器的内容。考虑到这种情况过程应改成:

   SOFTDLY PROC
   PUSH BX
   PUSH CX
   MOV BL,10
   ;内环延时10ms
   DELAY:MOV CX,2801
   WAIT: LOOP WAIT
   DEC BL
   JNZ DELAY
   POP CX
   POP BX
   RET
   SOFTDLY ENDP
   远过程调用时被调用过程必定不在本段内。

   例如,有两个程序段,
 
     其结构如下:
   CODE1 SEGMENT
   ASSUME CS:CODE1
    … FARPROC RPOC FAR
   … RET
    … FARPROC ENDP
   CODE1 ENDSCODE2 SEGMENT
   ASSUME CS:CODE2
    … CALL FARPROC
    … CALL NEARPROC
    … NEARPROC PROC NEAR
    … RET
   NEARPROC ENDP
   CODE2 ENDS

   7. 模块间通信的伪指令PUBLIC,EXTRN

PUBLIC和EXTRN伪指令可完成此功能,其一般格式为

PUBLIC 名称[,名称,……]
   EXTRN 名称:类型[,名称:类型……]
   例如:
      目的模块1 
   EXTRN VAR1:WORD,OUTPUT:FAR
   EXTRN VAR2:WORD
   LOCAL –DATA SEGMENT
   …LOCAL –DATA ENDS
   CODE SEGMENT
   ASSUME CS:CODE,DS:LOCAL --DATA
   START: MOV AX,LOCAL --DATA
   MOV DS,AX;初始化DS… MOV AX,SE :GVAR1
   MOV ES,AX;初始化ES
   ADD BX,ES:VAR1
    … MOV AX,SEGVAR2
   MOV ES,AX
   SUB ES:VAR2,50
   … JMP OUTPUT;段间跳转
    …CODE ENDS
   END START;目的模块2
   PUBLIC VAR1
   EXTDATA1 SEGMENT ;定义EXTDATA1数据段
    …VAR1: DW? ;定义变量VAR1
   EXTDATA1 ENDS
    … END
   ;

    目的模块3

   PUBLIC VAR2
   EXTDATA2 SEGMENT ;定义EXTDATA2数据段
    … VAR2: DW?
    … EXTDATA2 ENDS
   END
   PUBLIC OUTPUT
   ROUTINE SEGNENTASSUME CS:ROUTINE
    …OUTPUT LABEL FAR ;定义OUTPUT标号
    …ROUTIN EENDS
   END
8. 条件伪指令

  汇编语言提供了一组条件伪操作,用来指示汇编程序应该测试的条件,使汇编程序能根据测试结果有选择 地对源程序中的语句进行汇编处理。

  所有条件伪操作都采用如下格式:

   IF××××[〈表达式〉]
    … ELSE
    … ENDIF
9.宏命令伪指令

   在汇编语言书写的源程序中,若有的程序段要多次使用,为了简化程序书写,该程序段可以用一条宏命令来代替,而汇编程序汇编到该宏命令时,

  仍会产生源程序所需的代码。

   例如:

   MOV CL,4
   SAL AL,CL

  若该两条指令在程序中要多次使用,就可以用一条宏命令来代替。当然在使用宏命令前首先要对宏命令进行定义,

   例如:

   SHIFT MACRO
   MOV CL,4
   SAL AL,CL
   ENDM

   这样定义以后,凡是要使AL中内容左移4位的操作都可用一条宏命令SHIFT来代替。

   宏命令的一般格式为宏

   命令名MACRO[形式参量表]…宏体
   
   ENDMMACRO是宏定义符,是和ENDM宏定义结束符成对出现的。这两者之间就是宏体,也就是该宏命令要代替的那一段程序,

    例如:

   GADD MACRO X,Y,ADD
   MOV AX,Y
   ADD AX,Y
   MO VADD,AX
   ENDM
   
其中X,Y,ADD都是形式参量。调用时,下面宏命令书写格式是正确的:
  
   GADD DATA1,DATA2,SUM
   这里DATA1,DATA2,SUM是实参量。实际上与该宏命令对应的源程序为:
   MOV AX,DATA1
   ADD AX,DATA2
   MOV SUM,AX
   10.汇编结束伪指令END

该伪指令表示源程序的结束,令汇编程序停止汇编。因此,任何一个完整的源程序均应有END指令,

   其一般格式为

   END[表达式]
   
 其中表达式表示该汇编程序的启动地址。

     例如:
    … END START

   则表明该程序的启动地址为START。