设计汇编程序的步骤
设计汇编程序的步骤
第1章 标识符和表达式
1.1 标识符
标识符最多由31个字母、数字及规定的特殊字符(?、@、_、$)等组成,但它不能用数字开头。通常情况下,汇编语言不区分标识符中字母的大小写。
1.2 简单内存变量的定义
1.2.1 内存变量定义的一般形式
1.2.2 字节变量
DB/BYTE
1.2.3 字变量
DW/WORD
1.2.4 双字变量
DD/DWORD
1.2.5 六字节变量
DF/FWORD
1.2.6 八字节变量
DQ/QWORD
1.2.7 十字节变量
DT/TBYTE
1.3 调整偏移量伪指令
1.3.1 偶对齐伪指令EVEN
作用是:告诉汇编程序,本伪指令下面的内存变量从下一个偶地址单元开始分配。如果下一个偏移量是偶地址,那么,该伪指令不起作用,否则,汇编程序将空出一个字节,从下一个偶地址开始为其后变量分配内存单元。
1.3.2 对齐伪指令ALIGN
ALIGN Number
Number必须是2的幂,如:2、4、8和16等
作用是:告诉汇编程序,本伪指令下面的内存变量必须从下一个能被Number整除的地址开始分配。如果下一个地址正好能被Number整除,那么,该伪指令不起作用,否则,汇编程序将空出若干个字节,直到下一个地址能被Number整除为止。
1.3.3 调整偏移量伪指令ORG
ORG 数值表达式
作用是:告诉汇编程序,本伪指令下面的内存变量从该“数值表达式”所指定的偏移量开始分配。这将有可能会造成内存重叠。
以上3个伪指令中,EVEN使用频率较高。
1.3.4 偏移量计数器的值
汇编语言提供了一个特殊的符号“$”,用来引用偏移量计数器的值
W1 DW $,$
ORG $+3
B1 DB 43H
这里实在是不太明白是怎么回事,书上写得很糊涂。
1.4 复合内存变量的定义
1.4.1 重复说明符DUP
count DUP (表达式,表达式,…,表达式)
count是重复次数,(……)是被重复的部分。“表达式”可以是存储单元的初值,也可以是含有另一个DUP的式子。如果表达式有多个,则它们之间要用逗号分开。
BUFFER DB 100 DUP(?)
以上式子可以看出:用DUP说明内存变量相当于在高级语言中定义数组。
1.4.2 结构类型的定义
1. 结构类型的定义
结构名 STRUC[Alignment][,NONUNIQUE]
数据定义语句序列
结构名 ENDS
Alignment:可以用1、2、4来指定结构中字段的字节边界。与Align伪指令的作用相同。
NONUNIQUE:要求结构中的字段必须用全名才能访问。
与C语言的区别是:结构类型内的字段可以赋初值
2. 结构类型变量的定义
[变量名] 结构名<[字段值表]>
3. 结构类型字段的引用
结构变量名.字段名
1.4.3 联合类型的定义
1. 联合类型的说明
[联合类型名] UNION [Alignment][,NONUNIQUE]
数据定义语句序列
[联合类型名] ENDS
联合类型中的各字段相互覆盖,即同样的存储单元被多个不同的字段所对应,并且其每个字段的偏移量都为0
联合类型可以嵌套定义,但内层联合一定不能写联合类型名。
2. 联合类型变量的定义
联合数据类型的变量只能用第一个字段的数据类型来进行初始化。变量定义格式与结构类型一致
3. 联合类型字段的引用
与结构类型一致
1.4.4 记录类型的定义
1. 记录类型的说明
它是为按二进制位存取数据提供方便的。
记录名RECORD字段[,字段……]
其中字段代表:字段名:宽度[=初值表达式]
l 记录名就是该记录类型,记录类型可由多个字段组成,每个字段之间要用逗号分开,字段的属性包括字段名,宽度和初值,宽度表示该字段所占的二进制位数,它必须是一个常数。
l 如果记录总宽度大于8,则系统为该记录类型分配两个字节,否则只分配一个字节。
l 记录各字段宽度之和不能大于16(不知道是不是16位微机的限制,会不会只是16位微机限制16,而32位微机的限制是32?教材并未说明,不得而知。)
l 记录的最后一个字段排在所分配空间的最低位,然后对记录中的字段依次“从右向左”分配二进制位,左边没有分完的二进制位补0。
l 初值表达式给出的是该字段的缺省值。如果初值越过了该这字段的表示范围,将报错,没有初值表达式,则为0。
COLOR RECORD BLINK:1,BACK:3=0,INTENSE:1=1,FORE:3
2. 记录类型变量的定义
[变量名]记录名<字段值表>
l 变量名即为该记录类型的变量名称,它可省略。如果省略,则不能用符号名来访问该内存单元。
l 字段值表是给字段赋初值,中间用逗号分开,排列顺序及大小应与该记录说明时的各字段相一致。
l 如果记录变量的某字段用其说明时的缺省值,那么,可用逗号来表示,如果所有字段都如此,则不省去字段值表,但必须保留尖括号<>
COLOR1 COLOR <>,<1,7,0,5>,<1,,0,7>
3. 记录类型的专用操作符
WIDTH和MASK是作用于记录类型的两个专用保留字,利用它们可得到记录类型的不同属性。
这一段内容写得晦涩难懂,不明白是什么意思。
1.4.5 数据类型的自定义
新数据类型名TYPEDEF[位距][PTR]数据类型
位距是指NEAR FAR或PROC等。
PTR是说明类型为指针。
1.5 标号
标号是一种特殊的标识符,它代表代码段中的某个具体位置,主要用于表明转移的目标位置。
标号:汇编语言指令 ;注释
1.6 内存变量和标号的属性
1.6.1 段属性操作符
段属性操作符(SEG)返回该标识符所在段的段地址。
……
SCORE DW ?
NAME DB 10 DUP(10)
……
MOV AX,SEG SCORE ;AX获得代码段地址
MOV BX,SEG NAME ;BX获得代码段的地址
由于SCORE和Name在同一段中定义,所以,寄存器AX和BX的值是相等的。
1.6.2 偏移量属性操作符
偏移量属性操作符(OFFSET)返回该标识符离它所在段的段地址有多少字节。
MOV AX,OFFSET SCORE ;返回SCORE离数据段的偏移量
1.6.3 类型属性操作符
类型属性操作符(TYPE)是返回该变量所占字节数,或标号的远(FAR,返回-1)、近(NEAR,返回-2)类型。
1.6.4 长度属性操作符
长度属性操作符(LENGTH)是针对内存变量的操作符,它返回重复操作符DUP中的重复数。如果有嵌套的DUP,则只返回最外层的重复数;如果没有操作符DUP,则返回1。
1.6.5 容量属性操作符
SIZE变量=LENGTH变量×TYPE变量
1.6.6 强制属性操作符
PTR:强制类型转换
……
W1 DW 1234H,5678H
……
MOV BH,byte ptr W1 ;把W1的低字节传送给BH,执行后,BH=34H
1.6.7 存储单元别名操作符
THIS指当前地址。
THIS数据类型
WBUFFER EQU THIS WORD ;EQU是一个等价符号定义语句,在后面有介绍
BUFFER DB 20 DUP(?)
这样,就给同一块内存区取了两个变量名。
WBUFFER是字变量,而BUFFER是字节变量,它们的首地址是一致的。
1.7 表达式
1.7.1 进制伪指令RADIX
伪指令RADIX用来设置整数的缺省进制,宏汇编开始时所默认的整数进制为十进制。
.RADIX exp
伪指令前面要用点“.”开始,exp的值必须是区间[2,16]内的一个整数。
1.7.2 数值表达式
表达式
|
举例
|
常量
|
10101010B,234Q,1234D,’BX’
|
算术运算符
|
+,-,*,/,MOD
|
关系运算符
|
EQ(相等)、NE(不等)、LT(小于)、GT(大于)、LE(小于等于)、GE(大于等于)
|
逻辑运算符
|
AND、OR、NOT、XOR、SHL(左移位)、SHR(右移位)
|
其它操作符
|
HIGH(高8位),LOW(低8位),SEG(段地址),OFFSET(偏移量),TYPE(标识符类型),LENGTH(变量长度),SIZE(变量容量),WIDTH(记录/记录字段宽度),MASK(记录/记录字段的屏蔽位)
|
优先级:
l LENGTH、SIZE、WIDTH、MASK、()?[]、.(用于结构字段)、<>(用于记录类型)
l PTR、SEG、OFFSET、TYPE、THIS、:(用于段超越前缀)
l *、/、MOD、SHL、SHR
l HIGH、LOW
l +、-
l EQ、NE、LT、LE、GT、GE
l NOT
l AND
l OR、XOR
l SHORT
1.7.3 地址表达式
若有如下变量
B1DB10H,11H,12H
DB‘ABCD’
W1 DW1234H,5678H
那么表达式B1+1、B1+3和W1+2等都是地址表达式。
注意:地址表达式W1+1并不表示字变量W1之后一个字的存储单元,而是字变量W1之后一个字节的存储单元,它的存储单元值是7812H
1.8 符号定义语句
1.8.1 等价语句
符号名EQU表达式
其作用是用左边的符号名来代替右边的表达式。
注意:等价语句不会给符号名分配存储空间,符号名不能与其他符号同名,也不能被重新定义。
1.8.2 等号语句
汇编语言提供了用等号来定义符号常数的方法,即可用符号名代表一个常数。
符号名=数值表达式
ABC=10+200*5
ABC1=5*ABC+21
COUNT=1
COUNT=2*COUNT+1
用等号语句定义的符号可以被重新定义。
1.8.3 符号名定义语句
符号名LABEL类型
功能与THIS功能类似。
WBUFFER LABEL WORD ;WBUFFER与BUFFER具有相同的段地址和
BUFFER DB 200 DUP(0) ;偏移量,但它们的数据类型不同
……
NEXT1 LABEL FAR ;NEXT1和NEXT具有相同的段地址和偏移量
NEXT:MOV AX,BX ;NEXT1是远标号,NEXT是近标号
习题
1. 判断下列标识符的合法性
a) code 合法
b) Data 合法(不确定)
c) ABCDH 合法(同样不确定)
d) 1abcH 不合法(不能以数字开头)
e) eax 不合法(寄存器名不能作为标识符)
f) ???01 合法
g) A?@ 合法
h) www@zsu 合法
i) www@zsu.edu.cn不合法(点不能作为标识符)
j) AX$DX 合法
k) _BX 合法
l) CX 不合法(CX是寄存器名)
2. 按下面要求写出相应的数据定义语句(未指定变量名的,可任意指定或缺省)
1) 定义一个字节区域,第一个字节的值为20,其后跟20个初值为0的连续字节
db 20,20dup(0)
2) 定义一个以0为结束符的字符串,其初值为:The course is easy
STRING DB ‘The course is easy’,0
3) 定义一个以“$”为结束符的字符串,该串中含有换行符和回车符
String DB 13,10,’$’
4) 定义100个字,其初值为0
DW 100 dup(0)
5) 从一个偶地址开始定义一个字变量word
EVEN
word dw?
6) 先定义一个字符串String,其偏移量指定为10,其初值为“ABCDEF”,然后再定义3个字类型的数组Data,要求String和Data的偏移量相同。
7) 定义一个字符串String,其初值为“12345678”,再定义4个字类型的数组Data,要求String和Data共享同一片内存单元
3. 把下列C语言的变量定义语句改写成与之等价的汇编语言语句
4. 假设第3题中3组变量在内存中是连续存放的,且变量ch1的偏移量是20H,试求出其他每个变量的偏移量。
5. 按下列要求分别写出汇编语言的结构定义,如果没有说明结构分量的类型,请根据日常习惯自行指定其数据类型(可使用已有的结构定义)
6. 试求出第5题中各结构中字段的偏移量
7. 把下列C语言的结构或结构变量的定义改写为与之等价的汇编语言定义语句
8. 按下列要求分别写出汇编语言的记录定义
9. 试求出第8题中各记录中字段的宽度和屏蔽属性值
10. 假设变量B1的偏移量为12H,试求出以下变量的属性OFFSET、TYPE、LENGTH和SIZE的值
11. 试用3种方法定义字节变量(或字段名)B1和字变量(或字段名)W1,它们共享20个存储单元
12. 强制属性操作符会改变变量的定义属性吗?在C语言中存在类似功能的语句吗?若存在,请举例说明。
13. 假设有第10题中的变量定义,试写出符合要求的地址表达式。
14. 把下列C语言程序中的说明性语句改写成等价的汇编语言语句
15. 简述数值表达式与地址表达式的主要区别
16. 计算下列各数值表达式的值