DT(define ten bytes)
表4.2.8 ; DQ、DT例子的列表文件 00C0 ORG 00C0H 00C0 C223450000000000 DATA17 DQ 4523C2H ; 十六进制数 00C8 4948000000000000 DATA18 DQ 'HI' ; ASCII字符 00D0 0000000000000000 DATA19 DQ ? ; 分配8个字节单元 00E0 ORG 00E0H 00E0 2998564379860000 DATA20 DT 867943569829 ; 压缩的BCD数 0000 00EA 0000000000000000 DATA21 DT ? ; 分配10个字节单元 0000
对数据定义伪指令前面的变量还要注意它的类型属性问题。变量表示该伪指令中的第一个数据项的偏移地址,此外,它还具有一个类型属性,用来表示该语句中的每一个数据项的长度(以字节为单位表示),因此DB伪指令的类型属性为1,DW为2,DD为4,DQ为8,DT为10。变量表达式的属性和变量是相同的。汇编程序可以用这种隐含的类型属性来确定某些指令是字指令还是字节指令。
下例中变量OPER1为字节类型属性,OPER2为字类型属性,所以第一条MOV指令应为字节指令,第二条MOV指令应为字指令。而第三条指令的变量表达式OPER1+1为字节类型属性,AX却为字寄存器,第四条指令的OPER2为字类型属性,AL为字节寄存器,因此,汇编程序将指示这两条MOV指令出错:\类型不匹配\。
OPER1 DB ?, ? OPER2 DW ?, ? . .
.
MOV OPER1, 0 ;字节指令 MOV OPER2, 0 ;字指令
MOV AX, OPER1+1 ;错误指令:类型不匹配 MOV AL, OPER2 ;错误指令:类型不匹配
PTR属性操作符
下例中的两条MOV指令把OPER1+1的类型属性指定为字,把OPER2的类型属性指定为字节,这样指令中两个操作数的属性就一致了,汇编时就不会出错了。
OPER1 DB ?, ? OPER2 DW ?, ? . . .
MOV AX, WORD PTR OPER1+1 MOV AL, BYTE PTR OPER2
LABEL伪指令
例如:
BYTE_ARRAY LABEL BYTE
WORD_ARRAY DW 50 DUP (?)
在50个字数组中的第一个字节的地址赋予两个不同类型的变量名:字节类型的变量BYTE_ARRAY和字类型变量WORD_ARRAY。
在程序中访问数组单元时,要按指令类型来选择变量,如下面两条指令: MOV WORD_ARRAY + 2,0 ; 字指令,
; 把该数组的第3个和第4个字节置0
MOV BYTE_ARRAY + 2,0 ; 字节指令,
; 把该数组的第3个字节置0 4.2.5 表达式赋值伪操作EQU
EQU是一个赋值伪操作(伪指令),它给一个数据标号赋于一个常数值,但这个常数不占用存储单元。当这个数据标号出现在程序中时,汇编程序即用它的常数值代替数据标号。EQU可以在数据段之外使用,甚至可用在代码段中间。
= 伪操作
赋值伪操作\的作用与EQU类似。它们之间的区别是,EQU伪操作中的标号名是不允许重复定义的,而=伪操作是允许重复定义的。
使用EQU操作的优点可从下面的例子中看出:
COUNT EQU 25 COUNTER DB COUNT MOV AL, COUNT
假定在数据段和代码段中要多次使用一个数据(如25),那么在编程时凡是用到25的地方都可用数据标号COUNT来表示。如果程序想修改这个数据,那么只需修改EQU的赋值,而无须修改程序中其它部分,如COUNTER和MOV语句就不必修改。
EQU还可给表达式赋予一个名字,EQU的用法举例如下:
DATA EQU HEIGHT + 12 ; 地址表达式赋以符号名 ALPHA EQU 7 ; 常数赋以符号名
BETA EQU ALPHA-2 ; 把7-2=5赋以符号名BETA ADDR EQU VAR + BETA ; VAR+5赋以符号名ADDR。 B EQU [BP + 8] ; 变址引用赋以符号名 B
P8 EQU DS:[BP + 8] ; 加段前缀的变址引用赋以符号名P8
注意:在EQU语句的表达式中,如果有变量或标号的表达式,则在该语句前应该先给出它们的定义。如上例,ALPHA必须在BETA之前定义,否则汇编程序将指示出错。
例如, TMP EQU 5 TMP EQU TMP+1 则是错误语句,因为TMP已赋值为5,就不能再把它定义为其它数值。 而 TMP = 5
TMP = TMP+1 则是允许使用的,因为=伪操作允许重复定义。第一个语句TMP的值为5,第二个语句TMP的值就为6了。
4.2.6 地址计数器与对准伪指令
1.地址计数器$
在汇编程序对源程序汇编的过程中,使用地址计数器来保存当前正在汇编的指令的地址。地址计数器的值在汇编语言中可用$来表示。
当$用在伪指令的参数字段时,它所表示的是地址计数器的当前值
2.EVEN伪指令
EVEN伪指令使下一个变量或指令开始于偶数字节地址。
3. ALIGN伪指令
ALIGN伪指令使它后面的数据或指令从2的整数倍地址开始。其格式为:
ALIGN 2n (n为任意整数)
1.地址计数器$
汇编语言允许用户直接用$来引用地址计数器的值,例如指令:
JMP $+ 6
它的转向地址是JMP指令的首地址加上6。当$用在指令中时,它表示本条指令的第一个字节的地址。在这里,$+ 6必须是另一条指令的首地址。否则,汇编程序将指示出错信息。
当$用在伪指令的参数字段时,则和它用在指令中的情况不同,它所表示的是地址计数器的当前值。例如指令:
ARRAY DW 1, 2, $+ 4, 3, 4, $+ 4
假设汇编时ARRAY 分配的偏移地址为0074H,则汇编后,$+ 4所在的两个字单元: (ARRAY+4)=0078+4=007CH (ARRAY+0A)=007E+4=0082H
应当注意,ARRAY数组中的两个$+ 4得到的结果是不同的,这是由于$的值是在不断变化的缘故。当在指令中用到$时,它只代表该指令的首地址,而与$本身所在的字节无关。
2.EVEN伪指令
例如:
DATA_SEG SEGMENT
BYTE_DAT DB ? EVEN
WORD_DAT DW 100 DUP (?) DATA_SEG ENDS
一个字的地址最好从偶地址开始,所以对于字数组为了保证它从偶地址开始,可以在DW定义之前用EVEN伪指令来达到这一目的。
3. ALIGN伪指令
例如: .
ALIGN 4
ARRAY DD 100 DUP (?)
ALIGN伪指令保证了双字数组ARRAY地址边界从4的倍数开始。
ALIGN伪指令是将当前偏移地址指针指向2的乘方的整数倍的地址,如果源地址指针以指向2的乘方的整数倍的地址,则不作调整;否则将指针加以一个数,使地址指针指向下一个2的乘方的整数倍的地址。
当然,ALIGN 2和EVEN是等价的。
4.2.7 基数控制伪指令
.RADIX伪指令
.RADIX可以把默认的基数改变为2~16范围内的任何基数。其格式如下: .RADIX 基数值
其中基数值用十进制数来表示。 例如:
MOV BX, 0FFH ;16进制数标记为H MOV BL, 10000101B ;二进制数标记为B
MOV BX, 178 ;10进制为默认的基数,可无标记 .RADIX 16 ;以下程序默认16进制数
MOV BX, 0FF ;16进制为默认的基数,可无标记 MOV BX, 178D ;10进制数应加标记D
应当注意,在用 .RADIX 16把基数定为十六进制后,十进制数后面都应跟字母D。在这种情况下,如果某个十六进制数的末字符为D,则应在其后跟字母H,以免与十进制数发生混淆。
4.3.1.汇编语言源程序语句的格式
汇编语言源程序中的每个语句可以由四项组成,格式如下:
[名字] 操作 操作数 [ ;注释]
其中:
名字项是指一个标号或变量。
操作项是一个操作码的助记符,它可以是指令、伪指令或宏指令名。
操作数项由一个或多个表达式组成,它提供为执行所要求的操作而需要的信息。操作数项可以是常数、寄存器、标号、变量或由表达式组成。
注释项用来说明程序或语句的功能。\;\为识别注释项的开始。\;\也可以从一行的第一个字符开始,此时整行都是注释,常用来说明下面一段程序的功能。
上面四项中带方括号的两项是可选项。各项之间必须用\空格\(space)或\水平制表\(Tab)符隔开。
(1) 名字项 (2) 操作项 (3) 操作数项 (4) 注释项
(1) 名字项
源程序中用下列字符来表示名字: 字母A~Z 数字0~9
专用字符 ?、·、@ 、-、$
除数字外,所有字符都可以放在源语句的第一个位置。名字中如果用到·则必须是第一个字符。可以用很多字符来说明名字,但只有前面的31个字符能被汇编程序所识别。
一般说来,名字项可以是标号或变量。它们都用来表示本语句的符号地址,都是可有可无的,只有当需要用符号地址来访问该语句时它才需要出现。
· 标号:标号在代码段中定义,后面跟着冒号:,它也可以用LABEL或EQU伪操作来定义。此
相关推荐: