8086汇编语言程序设计(二)

 各种机器的汇编语言,其语法规则不尽相同,但基本语法结构形式类似。现以8086/8088汇编语言为例加以具体讨论。
  4.2.1 汇编语言的数据与表达式

  1.汇编语言的数据
  数据是汇编语言中操作数的基本组成成分,汇编语言能识别的数据有常数、变量和标号。
  (1)常数
  常数是指那些在汇编过程中已经有确定数值的量,它主要用作指令语句中的立即操作数、变址寻址和基址加变址中的位移量DISP或在伪指令语句中用于给变量赋初值。
  常数可以分数值常数和字符串常数两类。
  数值常数:以各种进位制数值形式表示,以后缀字符区分各种进位制,后缀字符H表示十六进制,O或Q表示八进制,B表示二进制,D表示十进制,十进制常省略后缀。
  字符串常数:用单引号括起来的一串ASⅡC码字符。如字符串"ABC"等效为41H、42H、43H一组数值常数,如"179"等效为31H、37H、39H一组数值常数。
  变量是代表存放在某些存储单元的数据,这些数据在程序运行期间可以随时修改。变量是通过变量名在程序中引用的,变量名在是存放数据存储单元的符号地址,它可以作为指令中的存储器操作数来引用。
  (2)变量
  变量一般都在数据段或附加段中使用数据定义伪指令DB、DW和DD来进行定义。定义变量就是给变量分配存储单元,且对这个存储单元赋予一个符号名――变量名,同时将这些存储单元预置初值。经过定义的变量具有以下3个属性:
  ①段属性:表示与该变量相对应的存储单元所在段的段基值;
  ②偏移量属性:表示该变量相对应的存储单元与段起始地址相距的字节数;
  ③类型属性:表示变量占用存储单元的字节数。这一属性是由数据定义伪指令DB、DW、DD来规定的。它们可以是单字节变量(或称字节变量)、双字节变量(或称字变量)、4字节变量(或称双字变量)。
  (3)标号
  标号是某条指令所在存储单元的符号地址,它指示指令在汇编语言程序中的位置,通常,标号用来作为汇编语言源程序中转移、调用以及循环等指令的操作数,即转移的目标地址。
  标号和变量相似,也有3个属性:段、偏移量和距离,前两个属性和变量的同名属性完全相同,而标号的第三个属性"距离"可以是  NEAR(近距离)或FAR(远距离)。

  NEAR(近距离):本标号只能被标号所在段的转移和调用指令所访问(即段内转移)。
  FAR(远距离):本标号可被其他段(不是标号所在段)的转换和调用指令所访问(即段间转移)。
  标号的基本定义方法是在指令的操作助记符前加上标识符和冒号,该标识符就是我们所要定义的标号。例如:
  START:PUSH DS
  标号还可以采用伪指令定义,如用LABEL伪指令和过程定义伪指令来定义,这将在后面叙述。
  2.表达式
  由常数、变量或标号和运算符连接而成的式子称为表达式,它是操作数的基本形式。表达式有数字表达式和地址表达式,汇编程序在汇编期间对表达进行计算,得到一个数值或一个地址。
  8086/8088汇编语言中的操作运算符分为:算术运算符、逻辑运算符、关系运算符、数值返回运算符、属性修改运算符。
  (1)算术运算符
  算术运算符包括加(+)、减(-)、乘(*)、除(/)和模运算符MOD。MOD施于操作,得到的是除法的余数,例如,27MOD 4,其结果为3。
  当算术运算为地址操作数时,应保证其结果是一个有意义的存储器地址,因而通常只使用+/-运算。
  (2)逻辑运算符
  逻辑运算符包括:非(NOT)、与(AND)、或(OR)和异或(XOR)。逻辑运算符的运算对象必须是数值型的操作数,并且是按位运算。应当注意逻辑运算符与逻辑运算指令之间的区别,逻辑运算符的功能是在汇编时由汇编程序完成,而逻辑运算指令的功能由CPU完成。
  (3)关系运算符
  关系运算符包括相等(EQ)、不等(NE)、小于(LT)、不大于(LE)、大于(GT)和不小于(GE)。关系运算符用于将两个操作数进行比较,若符合比较条件(即关系式成立),所得结果为全1;否则,所得结果为全0。
  (4)数值返回运算符
  数值返回运算符包括:段基值(SEG)、偏移量(OFFSET)、类型(TYPE)、长度(LENGTH)和字节总数(SIZE)。
  数值返回运算符用来把存储器操作数(变量或标号)分解为它的组成部分(段基值、偏移量、类型、元素个数总数和数据字节总数),并且返回一个表示结果的数值。这些运算符的格式如下:
  运算符 变量或标号
  ①段基值SEG运算符
  当运算符SEG加在一个变量名或标号的前面时,得到的运算结果是返回这个变量名或标号所在段的段基值。
  ②偏移量OFFSET运算符
  当运算符OFFSET加在一个变量名或标号前面时,得到的运算结果是返回这个变量或标号在它段内的偏移量。例如:
    MOV SI,OFFSET KX
  设KX在它段内的偏移量是15H,那么这个指令就等效于:
    MOV SI,15H

  这个运算符十分有用。例如,现有以ARRAY为首址的字节数组,为了逐个字节进行某种操作,可以使用下面的部分程序:
  
  在这段程序中,首先把数组变量的首字节偏移量送给SI,把寄存器SI作为数组的地址指针。这样在数组的逐个字节处理(即在LOP循环)中,用寄存器间接寻址方式,每处理完一个字节,就很方便地对地址指针SI进行修改,使它指向下一个字节。
  ③类型TYPE运算符
  运算结果是返回反映变量或标号类型的一个数值。如果是变量,则数值为字节数,DB为1,DW为2,DD为4,DQ为8,DT为10;如果是标号,则数值为代表标号类型的数值,NEAR为-1,FAR为-2。
  ④长度LENGTH运算符
  这个运算符仅加在变量的前面,返回的值是指数给变量的元素个数。如果变量是用重复数据操作符DUP说明的,则返回外层DUP给定的值;如果没有CUP说明,则返回的值总是1。
  对于数组变量,可以用重复操作表达式表达式表示,其格式为:
  重复次数DUP(操作数…操作数)
  其中,重复次数为正整数,DUP是重复操作符,括号中的操作数是重复的内容,操作数类型可以是字节、字或双字等。
  ⑤字节总数SIZE运算符
  SIZE运算符仅用于变量的前面,运算结果是返回数组变量所占的总字节数,也就是等于LENGTH和TYPE两个运算符返回值的乘积。
如数组变量ARRAY是用20HDUP(0)定义的,且数组元素的数据类型是字,则
     MOV AL,SIZE ARRAY
等效为:  MOV AL,40H

  (5)属性运算符
  属性运算符包括:类型修改(PTR)、短转移(SHORT)、类型指定(THIS)和段超越运算符(:)。这种运算符用来对变量、标号或某存储器操作数的类型属性进行修改。
  ①类型修改PTR运算符
  PTR运算符格式如下:
  类型 PTR 地址表达式
  其中,类型可以是BYTE(字节)、WORD(字)、DWORD(双字)、NEAR(近距离)、FAR(远距离)。
  运算结果是将地址表达式所指定的变量、标号或存储器操作数的类型属性,临时性地修改或指定为PTR运算中规定的类型。这种修改是临时性的,仅在有修改运算符的语句内有效。

  ②短转移SHORT运算符
  当JMP指令的目标地址与JMP指令之间的距离在-128~+127字节的范围内,可以用SHORT操作符来告诉汇编程序,将JMP指令汇编成两个字节的代码(一个字节为操作码,后一个字节为相对位移量)。例如:
    JMP SHORT NEAR_LABLE
  其中,目标标号NEAR_LABLE与JMP指令间的相对位移量在-128~+127个字节的范围内。
  ③类型指定THIS运算符
  THIS运算符的格式如下:
    THIS 类型
  其中,类型可以是BYTE、WORD、DWORD、NEAR或FAR。该操作符用来指定或补充说明变量或标号的类型。运算符THIS与LABEL伪指令有类似的效果,THIS运算符的应用举例,将在后面叙述。
  ④段超越运算符(跨段前缀)
  段超越运算符用来临时给变量、标号或地址表达式指定一个段属性。
  段超越运算符的格式为:
   段名:地址表达式
 或 段寄存器名:地址表达式
  例如:INC ES:[BP+3]
  ES:为跨段前缀,冒号":"前的ES段寄存器指明了操作数当前所在的段为附加数据段。如果没有跨段前缀"ES:",那么,由  [BP+3]地址表达式所表示的偏移地址将被系统默认为是在堆栈中。

 

3、运算符优先级(后期补充)

 

你可能感兴趣的:(汇编,汇编,语言,存储,byte,c)