表达式有一些属性,将在下面说明。
表达式的存储器类型(Expression Classes)
基于使用的操作数,表达式被分配一个存储器类型。下面是可以分配给表达式的存储器类型。
| 表达式的类型 | 说明 |
| N NUMB | 一个无存储器类型的数字 |
| C ADDR | 一个CODE地址符号 |
| D ADDR | 一个DATA地址符号 |
| I ADDR | 一个IDATA地址符号 |
| X ADDR | 一个XDATA地址符号 |
| B ADDR | 一个BIT地址符号 |
| CO ADDR | 一个CONST地址符号 |
| EC ADDR | 一个ECONST地址符号 |
| CE ADDR | 一个ECODE地址符号 |
| ED ADDR | 一个EDATA地址符号 |
| EB ADDR | 一个EBIT地址符号 |
| HD ADDR | 一个HDATA地址符号 |
| HC ADDR | 一个HCONST地址符号 |
典型的,表达式被赋予NUMBER类型,因为它们仅由数值型操作数组成。我们可以使用一个类操作数给一个表达式赋予一种存储器类型。一个地址符号值被自动分配其被定义的段的存储器类型。当一个值具有一种存储器类型时,表达式的构成有几条规则:
这就意味着一个存储器类型数值(即一个地址符号)加或减一个数字(或者一个数字加一个存储器类型数值)将得出一个具有存储器类型的数值。
例子
| data_address - 10 | 得出一个data_address数值 |
| 10 + edata_address | 得出一个edata_address数值 |
| (data_address - data_address) | 得出一个无存储器类型的数值 |
| code_address + (data_address - data_address) | 得出一个code_address数值 |
NUMBER类型的表达式几乎可以用在任何地方。具有存储器类型的表达式只能用在那种类型是正确的存储器类型的地方。
可重定位的表达式(Relocatable Expressions,又译作浮动表达式)
可重定位的表达式之所以这样命名,是因为它们含有一个到一个可重定位的或外部的符号的引用。这种类型的表达式只能被汇编器计算一部分,因为汇编器不知道的可重定位的段的最终位置。最终的计算由连接器完成。
一个可重定位的表达式通常只包含一个可重定位的符号,但是它还可以包含其它的操作数和操作符。我们可以通过加或减一个常数来修改一个可重定位的符号。
正确的可重定位表达式的例子
有两种基本类型的可重定位的表达式:简单的可重定位的表达式和扩展的可重定位的表达式。
简单的可重定位的表达式(Simple Relocatable Expressions)
这类表达式包含在可重定位的段中定义的符号。段和外部符号不允许出现在简单可重定位的表达式中。
简单可重定位表达式可以用在以下四种位置:
简单可重定位表达式的例子
| REL1 + ABS1 * 10 | |
| REL1 - ABS1 | |
| REL1 + (REL2 - REL3) | 假设REL1和REL2指向同一个段。 |
简单可重定位表达式的不正确形式
| (REL1 + ABS1) * 10 | 可重定位数值不可以做乘法。 |
| (EXT1 - ABS1) | 这是一个一般的可重定位表达式, |
| REL1 + REL2 | 我们不能把可重定位符号相加。 |
扩展的可重定位的表达式(Extended Relocatable Expressions)
这种表达式的规则与简单可重定位表达式的规则基本相同。段和外部符号可以出现在扩展的可重定位表达式中。扩展的可重定位表达式只可以用在生成代码为操作数的语句中;这些是:
扩展的可重定位表达式的例子
REL1 + ABS1 * 10
EXT1 - ABS1
LOW (REL1 + ABS1)
WORD2 (SEG1)
扩展的可重定位表达式的不正确的例子
| (SEG1 + ABS1) * 10 | 可重定位的值不可乘 |
| (EXT1 - REL1) | 我们只可以加、减绝对数量 |
| LOW (REL1) + ABS1 | LOW只可用于最终的可重定位的表达式。 |
表达式的例子
| EXTRN CODE (CLAB) | ; CODE空间的入口地址 |
| EXTRN DATA (DVAR) | ; DATA空间中的变量 |
| MSK EQU 0F0H | ; 定义一个符号来替代0xF0 |
| VALUE EQU MSK - 1 | ; 另一个常数符号化数值 |
| LVAL EQU 12345678H | ; LVAL获得数值12345678H |
| ?PR?FOO SEGMENT CODE | |
| RSEG ?PR?FOO | |
| ENTRY: MOV A, #40H | ; 将一个常数装入寄存器 |
| MOV R5, #VALUE | ; 装入常数符号化数值 |
| MOV R3, #(0x20, AND MASK) | ; 计算的例子 |
| MOV R7,#LOW (VALUE + 20H) | |
| MOV R6, #1 OR (MSK SHL 4) | |
| MOV R0, DVAR + 20 | ; 从地址DVAR+20中装载内容 |
| MOV R1, #LOW (CLAB + 10) | ; 装载地址CLAB+10的低字节 |
| MOV WR4, #WORD2 (LVAL) | ; 装载字LVAL的高字节 |
| MOV DR0, #ENTRY | ; 装载地址ENTRY的低位字到DR0 |
| MOVH DR0, #WORD2 (ENTRY) | ; 装载地址ENTRY的高位字到DR0 |
| MOV R4, @DR0 | ; 装载ENTRY的内容到R4 |
| ; | |
| MOV R5, 80H | ; 装载地址80H(= SFR P0)中的数据到R5 |
| MOV R5, EDATA 80H | ; 装载EDATA地址80H中的数据到R5 |
| SETB 30H.2 | ; 置位30H.2(长地址) |
| SETB 20H.2 | ; 置位20H.2(短地址) |
| END |
背景色为黄绿色的伪指令和选项只适用于AX51和A251。