• 汇编语言--标识符和表达式(四)(表达式与符号定义语句)


    7、表达式

    表达式是程序设计课程里的一个重要的基本概念,它可由运算符、操作符、括号、常量和一些符号连在一起的式子。在汇编语言中,表达式分为:数值表达式和地址表达式。

    (1)进制伪指令RADIX

    伪指令RADIX用来设置整数的缺省进制,宏汇编开始时所默认的整数进制为十进制。该伪指令的使用格式如下:

    .RADIX exp

    其中:伪指令前面要用点‘.’开始,exp的值必须是区间[2, 16]内的一个整数。

    该伪指令说明其下面整数的默认进制为exp。如果某整数已显式地表明了其进制,则该默认进制对其不起作用。在源文件中,可以使用多个RADIX伪指令来分别说明其后整数的默认进制,但为了避免引起不必要误会,我们不提倡这样去做。

    例如:

    .radix 8

    B1 DB 10, 11, 12 ;这三个数是八进制数

    DB 10D ;这数是十进制数,因为它已用'D'明确说明而不使用缺省进制

    .radix 10

    MOV AX, 1234 ;1234是十进制数

    MOV AX, 1234H ;1234H是十六进制数

    思考题:

    .radix 16

    DW 90D, 101B ;前者是十进制数,后者是二进制数吗?(是)

    (2)数值表达式

    数值表达式是在汇编过程中能够由汇编程序计算其值的表达式,其组成部分在汇编时就能完全确定。它通常是一些常量的运算组合。

    1)常量

    常量是一个立即数,直接写在汇编语言语句中,在程序的执行过程中,它不可能发生变化。通常,我们用二进制、八进制、十进制或十六进制来书写常量。

    例如:10101011B、324Q、1234D、1234H、0abcdH、'AB'等都是常量。

    在程序中,我们还可用伪指令.RADIX来改变数据的基数,在后面再详细讲解。

    2)算术运算符

    算术运算符包括符号:+(正)、-(负),运算符:+(加)、-(减)、*(乘)、/(除)和MOD(取模)。这些运算符和常量、括号可组成数值表达式。

    如:120+(321-90) mod 3,322*5/32,0abcdH+5,-590等

    3)关系运算符

    关系运算符包括符号:EQ(相等)、NE(不等)、LT(小于)、GT(大于)、LE(小于等于)和GE(大于等于)。这些关系运算符和常量、括号也可组成数值表达式。该表达式的计算结果规定如下:

    若关系不成立,则该数值表达式的计算结果为0;否则,其结果为0FFFFH。

    如:120H LT 100H+3,21H LE 21H等,它们的计算结果分别为:0和0FFFFH。

    4)逻辑运算符

    逻辑运算符包括按位操作符和移位操作符。具体是:AND(逻辑与)、OR(逻辑或)、NOT(逻辑非)、XOR(异或)、SHL(左移位)和SHR(右移位)。这些逻辑运算符和常量、括号可组成数值表达式。

    如:1 SHL 3,47H AND 0FH,NOT 56H等,它们的计算结果分别为:8,7和0A9H。

    5)表达式中的其它操作符

    汇编语言中,还有其它可在数值表达式中使用的操作符。它们是:

    a) HIGH(高8位)、LOW(低8位)

    b) SEG(段地址)、OFFSET(偏移量)

    c) TYPE(标识符类型)、LENGTH(变量长度)、SIZE(变量容量)

    d) WIDTH(记录/记录字段宽度)、MASK(记录/记录字段的屏蔽位)等

    在以上操作符中,只有HIGH和LOW没有介绍过,它们分别是选取表达式计算结果的高8位和低8位。其使用格式如下:

    HIGH 表达式   LOW 表达式

    如:HIGH (1234H+100H),LOW 1234H等,它们的选取结果分别为:13H和34H。

    6)运算符和操作符的优先级

    在汇编语言中,有许多各种运算符和操作符,它们的优先级按从高到低的排列如下:

    优先级:高 → 低

    LENGTH、SIZE、WIDTH、MASK、()、[]、.(用于结构字段)、<>(用于记录类型)

    PTR、SEG、OFFSET、TYPE、THIS、:(用于段超越前缀)

    *、/、MOD、SHL、SHR

    HIGH、LOW

    +、-

    EQ、NE、LT、LE、GT、GE

    NOT

    AND

    OR、XOR

    SHORT

    这些符号及其优先级并不要强记它们,有些符号同时出现的可能性非常小。在以后的学习中对常用的几个加以运用也就记住了。

    (3)地址表达式

    地址表达式是计算存储单元地址的表达式,它可由标号、变量名和由括号括起来的基址或变址寄存器组成。其计算结果表示一个存储单元的地址,而不是该存储单元的值。

    例如:

    B1 DB 10H, 11H, 12H

    DB 'ABCD'

    W1 DW 1234H, 5678H

    表达式B1+1、B1+3和W1+2等都是地址表达式,其值所代表的地址位置如图4.10所示。显然这些地址表达式所对应的存储内容分别为:11H、'A'和5678H。

    clip_image002

    注意:地址表达式W1+1并不表示字变量W1之后一个字的存储单元,而是字变量W1之后一个字节的存储单元,它的存储单元值是:7812H。

    8、符号定义语句

    在程序中,我们经常要使用一些常量或数值表达式,并把它们直接写在指令中,但当需要修改时,就要对它们逐个进行修改,这无疑会增加维护程序的工作量,而且每个常量或表达式所代表的含义也容易遗忘。

    为了改善程序的可读性,尽量减少维护程序的工作量,汇编语言提供了为常量或表达式定义一个符号名的方法。一旦定义了符号名,在指令中就可直接使用它们。(就像C语言的#define宏定义)

    (1)等价语句

    1)一般格式

    等价语句的一般使用格式如下:

    符号名 EQU 表达式

    作用是左边的符号名代表右边的表达式。

    注意:等价语句不会给符号名分配存储空间,符号名不能与其它符号同名,也不能被重新定义。

    2)用符号名代表常量或表达式

    当把一个常量或表达式定义成一个具有一定含义的符号名后,在程序中就可以用该符号名来代表该常量或表达式。

    例如:

    NUMBER EQU 100 ;给缓冲区的长度取一个符号名

    BUFF_LEN EQU NUMBER+2

    CR EQU 13 ;给“回车”符的ASCII码定义一个符号名

    LF EQU 10 ;给“换行”符的ASCII码定义一个符号名

    BUFFER DB NUMBER, ?, NUMBER DUP (?) ;用符号名来定义缓冲区

    3)用符号名代表字符串

    用一个具有一定含义的符号名定义某一个较长的字符串,在随后的程序中就用该符号名。例如:

    GREETING EQU "How are you!"

    在该定义之后,就可使用符号名GREETING来代表字符串"How are you!"。

    4)用符号名关键字或指令助忆符

    用一个(组)程序员自己习惯的符号名来代替汇编语言中的关键字或指令助忆符。但在此建议不要这样做,因为程序的编写者习惯,程序的其他阅读者可能会觉得很别扭。

    例如:

    MOVE EQU MOV ;给指令MOV取另一个符号名MOVE

    COUNTER EQU CX ;给寄存器CX取一个叫“计数器”的符号名

    上面的定义只是给原来的助忆符MOV和CX起了另一个别名,而原来助忆符MOV和CX仍然可以使用,所以,我们可编写如下语句:

    MOVE AX, CX ;相当于指令:MOV AX, CX

    MOV COUNTER, BX ;相当于指令:MOV CX, BX

    5)用符号名定义存储单元的别名

    可对一片存储单元定义另一个数据类型的符号名,有关叙述参见前面的操作符THIS。

    例如:

    WORD1 EQU THIS WORD ;给后面的字节存储单元取一个字属性的符号名

    BYTE1 DB 12h, 21h

    FLAG DW 1234H

    FLAG1 EQU byte ptr FLAG ;给FLAG的低字节取一个字节属性的符号名

    FLAG2 EQU byte ptr FLAG+1 ;给FLAG的高字节取一个字节属性的符号名

    有了上述定义后,可编写如下语句:

    MOV AX, WORD1 ;执行后,(AX)=2112H

    MOV BL, FLAG1 ;执行后,(BL)=34H

    (2)等号语句

    汇编语言提供了用等号来定义符号常数的方法,即可用符号名代表一个常数。其一般格式如下:

    符号名=数值表达式

    数值表达式在汇编时应该可以计算出数值,它不能含有向前引用的符号名称。用等号语句定义的符号可以被重新定义。例如:

    ABC = 10 + 200 * 5 ;ABC的值为1010

    ABC1 = 5 * ABC + 21 ;ABC1的值为5071

    COUNT = 1 ;COUNT的值为1

    COUNT = 2*COUNT + 1 ;COUNT的值为3

    (3符号名定义语句

    符号名定义语句LABEL与前面的操作符THIS功能类似,该语句定义一个指定的符号名,该符号名的段地址和偏移量与下面紧跟存储单元的相应属性相同,但该符号的类型是新指定的。LABEL语句的一般格式如下:

    符号名 LABEL 类型

    其中:常用的类型有BYTE、WORD、DWORD、NEAR和FAR等。

    例如:

    WBUFFER LABEL WORD

    BUFFER DB 200 DUP(0)

    NEXT1 LABEL FAR

    NEXT: MOV AX, BX

    WBUFFER与BUFFER具有相同的段地址和偏移量,但它们的数据类型不同。

    NEXT1和NEXT具有相同的段地址和偏移量,NEXT1是“远”标号,NEXT是“近”标号。

    标号NEXT1和NEXT可用于不同的情况。当在同一个模块内转移时,可使用标号NEXT;当在不同的模块之间进行转移时,需要使用“远”标号NEXT1。

  • 相关阅读:
    CAST和CONVERT
    #pragma 预处理指令详解
    Android系统移植主要事项
    Java动态绑定机制的内幕
    Java接口和抽象类用法总结
    Android工程的编译过程
    点击按钮,并且实现增加一个按钮的效果 (附效果图)
    iOS-设置导航栏"返回"按钮 (附效果图)
    常用代码整理(重要)
    NSTimer 的暂停与恢复运行。
  • 原文地址:https://www.cnblogs.com/CIreland/p/9860258.html
Copyright © 2020-2023  润新知