微型计算机汇编语言及汇编程序文档格式.docx
《微型计算机汇编语言及汇编程序文档格式.docx》由会员分享,可在线阅读,更多相关《微型计算机汇编语言及汇编程序文档格式.docx(49页珍藏版)》请在冰豆网上搜索。
变量是代表存放在某些存储单元的数据,这些数据在程序运行期间随时可以修改。
为了便于对变量的访问,它常常以变量名的形式出现在程序中,它可以认为是存放数据存储单元的符号地址。
(1)变量的定义与预置
定义变量就是给变量分配存储单元,且对这个存储单元赋于一个符号名——变量名,同时将这些存储单元预置初值。
VAR-DATASEGMENT;
定义一个数据段
DATA1DB12H;
定义DATA1=12H
DATA2DB34H;
定义DATA2=34H
DATA3DW5678H;
定义DATA3=5678H
VAR-DATAENDS
经过定义的变量,每个变量均有3个属性。
1)段属性(SEG):
表示变量存放在哪一个逻辑中,例如,上面所定义的变量,它就是在数据段中。
当在指令中要对这些变量进行存取操作时,事先要把它们所在段的段基值存放在某一个段寄存器(如DS)中。
2)偏移量属性(OFFSET):
表示变量在逻辑段中离段起始点的字节数。
例如,变量DATA1的偏移量为0,而DATA2的偏移量为1,DATA3偏移量为2。
上述段和偏移量两个属性就构成了变量的逻辑地址。
3)类型属性(TYPE):
表示变量占用存储单元的字节数。
这一属性是由数据定义伪指令DB、DW、DD来规定的。
变量DATA1、DATA2是用DB定义的,它的类型属性为字节;
而DATA3是用DW定义的,类型属性为字;
如果用DD定义,类型属性为双字。
(2)数据定义伪指令
这种伪指令主要为数据项分配存储单元并预置初值。
它的格式为:
其中表达式1、表达式2、…是给变量赋予的初值。
表达式可以有以下几种情况:
1)数值表达式。
DAT-BYTEDB50H,50
变量DA-BYTE的内容为50H,它的下一个字节为32H。
2)?
表达式:
不带引号的?
表示可预置任何内容。
例:
DA-BDB?
,?
DA-WDW?
第一条语句是要求汇编程序分配两个字节单位,第2条语句是要求分配两个字单元。
这些单元里现在可以是任意值。
3)字符串表达式:
对于DB伪指令,为字符串中每一个字符分配一个字节单元。
字符串必须是用引号括起来且不超过255个字符。
字符串自左至右以字符的ASCII码按地址递增的排列顺序依次存放。
STRING1DB‘ABCDEF’,它们在存储器中存放的情况见下图:
对于DW的伪指令,可以给两个字符组成的字符串分配两个字节存储单元,而且这两个字符ASCII码的存储顺序是前一字符在高字节,后一个字符在低字节,每一个数据项不能多于两个字符。
如STRING2DW‘AB’,‘CD’,‘EF’,具体在存储器中存放的情况见上图。
对于DD伪指令,仅可给两个字符组成的字符串分配4个字节单元,且这两个字符ASCII码是存储在两个低字节中,两个高字节均存放00H。
STRING3DD‘AB’,‘CD’,具体在存储器中存放的情况见上图。
4)带DUP表达式:
DUP是定义重复数据操作符。
在表达式中,使用DUP操作符格式是:
其中表达式1是重复的次数,表达式2是重复的内容。
如
D-B1DB20HDUP(?
)
D-B2DB10HDUP(‘ABCD’)
D-W1DW10HDUP(4)
第1语句表示保留20H个字节,每个字节可预置任意内容。
第2语句是重复10H个字符串“ABCD”,共占有40H个字节。
第3语句是重复10H个字单元,每个单元预置为4,共占有20H个字节。
3、标号
标号是一条指令目标代码的符号地址,它常作为转移指令的操作数。
例如
START:
…
…
AA:
与变量相似,每个标号亦具有3个属性:
(1)段属性(SEG)表示这条指令目标代码在哪个逻辑段中。
(2)偏移量属性(OFFSET)表示这条指令目标代码的首字节在段内离段起始点的字节数。
同样,上述两个属性构成了这条指令目标代码首字节的逻辑地址。
(3)距离属性:
表示本标号可作为段内或段间的转移特性。
距离属性分为两种:
NEAR,本标号只能被标号所在段的转移和调用指令所访问;
FAR,本标号可被其他段的转移和调用指令访问。
三、表达式和运算符
表达式由操作数和运算符组成,在汇编时一个表达式得到一个值。
用一个运算符可以对一个操作数或几个操作数进行运算,这就构成一个表达式,从而得到一个新的值。
86系列CPU包括六类运算符:
算术运算符、逻辑运算符、关系运算符、分析运算符、组合运算符和分离运算符。
1、算术运算符
+、-、×
、÷
(/)是加减乘除运算符。
MOD是除法取余运算符。
例如:
32MOD5=2
SHL是左移操作符。
21HSHL2=84H
SHR是右移操作符
2、逻辑运算符
AND是逻辑“与”操作符,例如:
24HAND0FH=04H
OR是逻辑“或”操作符,例如:
24HOR0FH=2FH
XOR是逻辑“异或”操作符,例如:
24HXOR0FH=2BH
NOT是逻辑“非”操作符,例如:
24HNOR0FH=0DBH
3、关系运算符
关系运算符是逻辑判定式,当为“真”时结果取0FFFFH,当为“假”时结果取为0。
关系运算是数值型的。
EQ等于。
例如,已赋给符号PP为25,则25EQPP=0FFFFH
NE不等于。
例如,25NEPP=0
LT小于。
例如,25LT26=0FFFFH
LE小于等于。
例如,25LE26=0FFFFH
GT大于。
例如,26GT25=0FFFFH
GE大于等于,例如,24GEPP=0
4、分析运算符
(1)SEG求段基址
格式:
SEG<
符号名>
(2)OFFSET求偏移地址
OFFSET<
(3)TYPE求符号名类型值
TYPE<
符号名类型值见下表:
类型
1字节
2字节
4字节
8字节
10字节
近程
远程
类型值
1
2
4
8
10
-1
-2
(4)SIZE求为符号名分配的字节数
SIZE<
为符号名定义的数据项必须是用重复格式DUP()定义的。
(5)LENGTH求为符号名分配的项数
LENGTH<
为符号名定义的数据项必须是用重复格式DUP()定义的。
=(LENGTH<
)*(TYPE<
5、组合运算符
组合运算符是用来改变或建立符号名的新类型。
(1)定义符号名为新类型
<
类型>
PTR<
设内存变量D1是字节属性,把它的两个字节内容送到AX中。
属性符号见上表。
MOVAX,WORDPTRD1
这里的符号名可以是间址、变址寻址、基址加变址寻址表示的存储器操作数。
(2)指定新类型
与PTR类似,可为某个符号名建立新类型。
THIS<
LABCEQUTHISBYTE
LABDDW4321H,2255H
MOVAL,LABC;
AL=21H
MOVAX,LABD;
AX=4321H
符号名LABC与LABD有相同的段地址和偏移地址,但LABC是字节类型,而LABD是字类型。
6、分离运算符
(1)LOW取低字节
LOW<
表达式>
(2)HIGH取高字节
SSY=2050H
MOVAL,LOW3080H;
AL=80H
MOVAH,HIGHSSY;
AH=20H
MOVCL,LOW3A4BH;
CL=4BH
7、汇编运算符的优先级
优先级
序号
运算符
括号中的表达式
LENGTH、SIZE、WIDTH、MASK
PTR、OFFSET、SEG、TYPE、THIS、段前缀(段寄存器名)
3
HIGH、LOW
*、/、MOD、SHL、SHR
5
+、-、
6
EQ、NE、LT、LE、GT、GE
7
NOT
AND
9
OR、XOR
SHORT
第二节伪指令
伪指令没有对应的机器指令,它不是由86系列CPU来执行,而是由MASM-86识别,并完成相应的功能。
它在很大程序上规定了MASM-86的性能,因此也可称之为汇编命令。
MASM-86中使用的伪指令可分成14类,下面逐一进行介绍。
1、符号定义伪指令(赋值语句)
(1)〈名字〉EQU〈表达式〉
(2)〈名字〉=〈表达式〉
该语句把表达式的值赋给符号名,在同一程序中,用EQU语句赋值的符号名不能被重新赋值,但用“=”号赋值的符号名可以被重新赋值。
“<
>
”号表示此项不能默认,但符号不需要输入。
2、内存数据定义伪指令
(1)字节定义伪指令
[名字]DB〈表达式或数据项表〉
表达式值或项表中的每一项是一个字节数,它们从符号名地址开始按字节连续存放,直到表中数据项结束(地址递增方向)。
方括号[]表示该项可以默认。
(2)字定义伪指令
[名字]DW〈表达式或数据项表〉
除表达式值或项表中的每一项是两个字节数之外,其它与DB伪指令相同。
(3)4字节定义伪指令
[名字]DD〈表达式或数据项表〉
表达式值或项表的每一项是4个字节数,该语句可以定义有小数点的十进制数或用科学表示法表示的数据,此时在汇编时被译成4字节浮点数,尾数在低地址一端,阶码在高地址一端。
浮点格式在第一章中介绍。
N1DD25ABH,0A002677H
N2DD2.5,3.2E+2
(4)8字节定义伪指令
[名字]DQ〈表达式或数据项表〉
表达式值或数据项表的每一项是8字节数,各项从小地址一端连续存放,允许浮点数形式,与DD伪指令相同。
高4个字节填0。
(5)10字节定义伪指令
[名字]DT〈表达式或数据项表〉
表达式值或数据项表的每一项是10字节数,允许浮点数形式,与DQ伪指令相同;
若项表中的数据项是十进制数书写的,汇编程序按组合的BCD码格式存放,最低字节在高地址一端存放,数据的最高字节的最高位是符号位,“0”表示正,“1”表示负。
表达式或数据表多于一项时,项与项之间用逗号或空格分隔,表达式或数据项重复书写时,可用重复格式简写。
D1DB12H,13H,12H
D1DB3DUP(12H)
在指令中引用上述定义的符号时,必须考虑符号名的类型,否则会出现错误提示。
MOVAX,D1;
D1类型错误
MOVAX,WORDPTRD1;
正确
3、段定义伪指令
存储器在逻辑上是分段的,各段的定义由伪指令实现。
〈段名〉SEGMENT[定位方式][连接方式][‘类别名’]
…
〈段名〉ENDS
段定义伪指令为程序的汇编和连接说明了段名、分段的各种属性以及分段的开始和结束。
段名是自定义符,开始的段名与结束的段名必须相同。
段的长度不超过64KB。
SEGMENT后面的参数是可选项。
(1)定位方式(定位类型):
定位方式指定段的起始地址边界,方式有4种。
PAGE——指定起始地址的低8位是0,即其值能被256整除(称为页边界)。
PARA——指定起始地址的低4位是0,即其值能被16整除(称为段边界)。
这是系统隐含定位方式。
WORD——指定起始地址的低位是0,即其值能被2整除(称为字边界)。
BYTE——指定起始地址是任意值。
以上4种边界如下所示:
×
×
00000000PAGE
0000PARA
00WORD
BYTE
(2)连接方式(组合类型):
连接方式告诉连接程序本段与其他段可按某种方式连接,它有6种选择。
PUBLIC——告诉连接程序把本段与其他同名同类别的段连接起来,公用一个段的起点地址,形成一个物理段。
STACK——表示本段是堆栈段,连接方式同PUBLIC,连接后的段起始地址在SS寄存器中。
连接程序要求源程序至少要有一个堆栈段,否则提示错误,此时,系统取约定堆栈段值。
NONE(空缺)——表示本段不与任何段连接,这是系统隐含连接方式。
COMMON——表示本段与同名同类别的段共用同一段起始地址,即同名同类段相重叠,段的长度是最长段的长度。
MEMORY——表示本段在连接时定位在所有段之上,即高地地址。
AT表达式——表示本段定位在表达式值指定的段地址处。
(3)‘类型名’:
类型名是合法的自定义符,它必须用单引号括起来。
凡是类别名相同的段在连接时均按先后顺序连接起来。
4、段寄存器说明伪指令
ASSUME段寄存器:
段定义名1[,段寄存器:
段定义名2,…]
该伪指令告诉汇编程序在汇编时,段寄存器CS:
,DS:
,SS:
和ES:
应具有的符号段基址,以便汇编指令时确定段和建立错误信息。
但是段寄存器实际值(CS除外)还要由传送指令在执行程序时赋值。
5、过程(子程序)定义伪指令
〈过程名〉PROC[NEAR]([FAR])
〈过程名〉ENDP
过程名是自定义符。
定义过程是为实现子程序调用而设的。
调用格式为:
CALL〈过程名〉
过程由RET指令返回,它可以不是最后一条指令,它在过程中可以设多点返回。
过程起始名和终止名必须相同。
类型NEAR和FAR默认时系统约定是近过程,当选NEAR时,过程是段内调用,过程中的RET是段内返回。
当选FAR时,过程是段间调用,过程中的RET是段间返回。
6、模块开始伪指令
NAME模块名
该伪指令指明程序模块的开始,并指出模块名。
模块名是自定义符,它不能是系统保留字,每次汇编只能出现一次。
若该伪指令默认,则取TITLE语句中的页标题前6个字符;
若没有TITLE语句,则取源程序文件名为模块名。
7、模块结束伪指令
EDN[启动标号或过程名]
该伪指令告诉汇编程序源文件结束,并给执行程序的入口位置。
启动地址只有在主模块才有意义。
8、定位伪指令
ORG〈表达式〉
该指令把以下语句定义的内存数据或程序,从表达式指定的起点(偏移地址)开始连续存放,直到遇到新的ORG指令。
表达式的值是一个无符号数。
9、列表伪指令
(1)建立标题
TITLE标题
为列表文件每页第一行定义大标题
(2)建立小标题
SUBTTL小标题
为列表文件每页定义小标题,输出在大标题之后
(3)自动排版(行数、列数)
PAGE行数、行字数
为列表文件定义每页行数(10~255)和每行字符数(60~132),默认值是66行,80列
10、系统隐含进位制伪指令
·
RADIX表达式
定义在源程序中书写数据时的隐含进位制方式。
表达式的值是2~16之间的十进制数,要遇到新的·
RADIX语句后才改变隐含进位制。
例如,表达式取值是8时,书写默认后缀的数据是八进制而不是十进制。
11、连接伪指令
连接伪指令主要解决多模块的连接问题,对一个大程序来说,往往要分模块编程,分模块调试,最后再系统连接与调试。
连接伪指令为多模块连接进行说明。
(1)公用符号伪指令
PUBLIC〈符号名1[,符号名2,…]〉
本模块用PUBLIC伪指令说明的自定义符号名可由其他程序模块引用,没有说明的符号名不能被其他模块引用。
符号名可以是变量名、标号、过程名或符号常量等。
(2)引用符号伪指令
EXTRN〈符号名1:
类型[,符号名2,类型…]〉
在本模块引用的在其他模块定义的符号名必须用EXTRN进行说明,否则不能引用。
此外还应注意,所引用的外模块定义的符号名还应是用PUBLIC伪指令说明过的。
类型是指符号名的类型,它们可以是:
内存变量型:
BYTE,WORD,DWORD
过程型:
NEAR,FAR
数值型:
ABS
(3)插入伪指令(或称包含伪指令)
INCLUDE〈模块名〉
在本模块汇编时,把另一模块插入该伪指令处一起汇编,被插入的模块可以是不完整的。
(4)合段伪指令(或称组合伪指令)
组合GROUP〈段名1[,段名2,…]〉
把其后指定的段组合在一个64KB的物理段中,组名和段名都是自定义符,但不可重名。
12、记录伪指令
(1)记录定义伪指令
记录名RECORD〈段名1:
字段宽[,段名2:
字段宽,…]〉
记录定义伪指令完成对内存单元二进制位的定义,这在实际应用中可以实现按位开关量或按位组合信息的处理。
记录名和字段名是自定义符,字段宽度是1~16常数。
记录是把1~16个二进制位分为段并赋于一个字段名。
记录定义伪指令不真正为记录分配内存单元,它只是在汇编时进行记录名、字段名以及记录长度的说明。
(2)记录存储单元分配及赋值
[变量名]记录名胜古迹〈字段值表〉
变量名是自定义符,字段值表中的各字段值赋给记录的各字段中,其顺序与记录定义的顺序相同,若字段值表中的某些项默认,则默认值为0。
应用时尖括号“〈〉”不能默认。
TANRECORDX:
6,Y:
4,Z:
APTAN〈5,10,,〉
BPTAN〈12,,20〉
此例在存储器中分配两个记录,每个记录长是两个字节(16位)。
(3)记录操作符
1)WIDTH
WIDTH记录名(或字段名)
用该操作符可求出记录或字段所占的位数。
MOVAX,WIDTHTAN;
16送AX
MOVBH,WIDTHY;
4送BH
2)MASK
MASK记录字段名
用该操作符可返回记录字段位或使用情况,它是8位或16位二进制数,1表示是该字段位,0表示不是该字段位。
MOVAL,MASKZ;
00111111B送AL
MOVBL,MASKZ;
11111100B送BL
13、结构伪指令
结构伪指令是把多个数据定义语句组织成一个结构,而把每一个数据定义语句称为一个结构字段,内存变量名称为字段名。
(1)结构定义
结构名STRUC
〈数据定义语句〉
结构名ENDS
结构定义不真正为结构分配存储空间,它是在汇编时进行结构说明的。
(2)结构存储单元分配及赋值
[变量名]结构名胜古迹〈字段值表〉
变量名是自定义符,字段值表的各字段值赋给结构的各字段中,其顺序与结构定义的顺序相同,若字段值表中某些项默认,则保留初始值。
TAN1STRUC
D1DB2,25,10H
D2DB‘WTAN’
SYYDB?
TAN1ENDS
SUNTAN1〈,‘DOG1’,2〉
CATTAN1〈,‘beg’,〉
在存储器中分配了两个结构单元。
(3)结构引用
结构变量名.结构字段名
MOVDH,SUN.SYY;
2送DH
MOVAL,CAT.SYY;
0送AL
14、块注释伪指令
COMMENT定界符注释定界符
定界符是自定义任何非空字符。
例如,COMMENT/注释文/
第三节宏指令
为了简化汇编程序的书写,把一些频繁出现的程序段定义为“宏指令”,当程序中遇到这个程序段时,只需用一条宏调用语句,这样有效地缩短了源程序的长度,使源程序易读,也减少了由于重复书写而此起的错误。
宏调用与过程调用的区别如下:
(1)宏调用语句由宏汇编程序MASM-86中的宏处理程序来识别,并完成相应的处理;
而调用过程的CALL语句由CPU来执行。
(2)汇编语言源程序在汇编过程中要将宏指令所代替的程序段汇编成相应的机器代码,并插入到源程序的目标代码中,每次调用均要插入。
而“过程”经汇编后的机器代码是与主程序分开而独立存在的,其目标代码在存储器中只需保留一份。
(3)过程调用需要保留程序的断点和现场,待过程执行完毕还要恢复现场和断点,这些操作需要耗费CPU的时间,而宏调用则不需进行这些操作。
(4)在每次宏调用时允许修改有关参数,使得同一条宏指令在各次调用过程中可完成不同的操作;
而“过程”一旦被定义,一般不允许修改。
在使用高级语言时,各语句的定义是由相应的编译程序去处理的,但宏指令却不一样,它需要定义。
宏指令的使用要经过如下3个步骤:
(1)宏定义:
对各个宏指令进行定义,并分别起一个名字。
(2)宏调用:
在需要使用的地方,通过宏指令名来调用它。
(3)宏扩展:
由宏汇编程序用宏定义中的指令来代替宏调用中的宏指令名。
1、宏代换语句
宏名MACRO[形式参数1,形式参数2,。
。
]
宏体(指令序列)
ENDM
功能:
宏代换语句为指令序列定义一个宏名,称为宏指令,宏名可以像指令一样在程序中引用。
形式参数是任选项,可用来代换宏体中某些参数或符号。
当代换指令中的称号时,在其前面需加一个宏代换符&
AHMARCOY,X
MOVCL,X
RO&
YCL
经宏代换语句定义的宏名,在应用时可直接引用,称为宏调用。
宏调用时,形式参数要用实在参数取代,顺序也应与形式参数顺序相同。
AHR,5
源程序在汇编后,在引用宏名的地方,插入了宏体,它在。
LST文件列表时可以看到,其中有+号的指令便称为宏扩展。
宏指令可以嵌套,并可与子程序联合嵌套