汇编语言的特点
1.助记符指令和机器指令一一对应。用汇编语言编制的程序,效率高,占用存贮空间小,运行速度快。因此汇编语言能编写出最优化的程序,而且能反映出计算机的实际运行情况。
2.汇编语言编程比高级语言困难。因为汇编语言是面向计算的,程序设计人员必须对计 算机有相当深入的了解,才能使用汇编语言编制程序。
3.汇编语言能直接和存储器及接口电路打交道,也能申请中断。因此汇编语言程序能直接管理和控制硬件设备。
4.汇编语言缺乏通用性,程序不易移植。各种计算机都有自已的汇编语言,不同计算机的汇编语言之间不能通用。但是掌握了一种计算机的汇编语言,就有助于学习其它计算机的汇编语言。
汇编语言的语句格式
各种汇编语言的语句格式是基本相同的,表示如下:
[标号:] 操作码助记符 [第一操作数] [,第二操作数] [,第三操作数] [;注释]
即一条汇编语句是由标号、操作码、操作数和注释四个都分所组成。其中方括号括起来的是可选择部分,可有可无,视需要而定。
1. 标号
标号是表示指令位置的符号地址,它是以英文字母开始的由1~6个字母或数字组成的字符串,并以“:”结尾。通常在子程序入口或转移指令的目标地址处才赋予标号。有了标号,程序中的其它语句才能访问该语句。MCS-51汇编语言有关标号的规定如下:
1).标号是由1~8个ASCII字符组成,但头一个字符必须是字母,其余字符可以是字母、数字或其它特定字符。
2).不能使用本汇编语言已经定义了的符号作为标号,如指令助记符,伪指令记忆符以及寄存器的符号名称等。
3).标号后边必须跟以冒号。
4).同一标号在一个程序中只能定义一次,不能重复定义。
5).一条语句可以有标号,也可以没有标号,标号的有无决定着本程序中的其它语句是否需要访问这条语句。
2. 操作码
操作码助记符是表示指令操作功能的英文缩写。每条指令都有操作码,它是指令的核心部分。操作码用于规定本语句执行的操作,操作码可为指令的助记符或伪指令的助记符,操作码是汇编指令中唯一不能空缺的部分。
3. 操作数
操作数用于给指令的操作提供数据或地址。在一条指令中,可能没有操作数,也可能只包括一项,也可能包括二项、三项。各操作数之间以逗号分隔,操作码与操作数之间以空格分隔。操作数可以是立即数,如果立即数是二进制数,则最低位之后加“B”;如果立即数是十六进制数,则最低位之后加“H”;如果立即数是十进制数,则数字后面不加任何标记。
操作数可以是本程序中已经定义的标号或标号表达式,例如MOON是一个已经定义的标号,则表达式MOON+1或MOON-1都可以作为地址来使用。操作数也可以是寄存器名。此外,操作数还可以是位符号或表示偏移量的操作数。相对转移指令中的操作数还可使用一个特殊的符号“$”,它表示本相对转移指令所在的地址,例如:JNB TF0,$ 表示当TF0位不为0时,就转移到该指令本身,以达到程序在“原地踏步”等待的目的。
4. 注释
注释不属于语句的功能部分,它只是对每条语句的解释说明,它可使程序的文件编制显得更加清楚,是为了方便阅读程序的一种标注。只要用“;”开头,即表明后面为注释内容,注释的长度不限,一行不够时,可以换行接着书写,但换行时应注意在开头使用“;”号。
5. 分界符(分隔符)
汇编程序在上述每段的开头或末尾使用分隔符把各段分开,以便于区分。分界符可以是空格、冒号、分号和逗号等。这些分界符在MCS-51汇编语言中使用情况如下:
1).冒号(:)用于标号之后。
2).空格 ( )用于操作码和操作数之间。
3).逗号(,)用于操作数之间。
4).分号(;)用于注释之前。
例如MOV A,#0AH表示取一个(立即)数0A(十六进制,如转换成二进制为00001010)传送到A累加器。
所谓机器语言即指令的二进制编码,而汇编语言则是指令的表示符号 。在指令的表达式上也不会直接使用二进制机器码,最常用的是十六进制的形式。
汇编语言:伪指令详解
AT89S51的伪汇编指令
汇编语言除了定义了汇编指令外,还定义了一些汇编伪指令,以支持汇编的运行。伪指令是汇编时不产生机器语言代码的指令,是CPU不能执行的指令,仅提供汇编用的某些控制信息。AT89S51汇编语言常用的伪指令有如下几条。
(1)ORG定位伪指令
格式:ORG m
m一般是16位二进制数,m指出在该指令后的(伪)指令的汇编地址,即生成的机器指令的起始存储器地址。它必须放在每段源程序或数据段的开始行,在一个汇编语言的源程序中允许存在多条定位伪指令,但其中每一个m值都应和前面生成的机器指令存放地址不重叠。
例如下面的代码。
ORG 1000H
START: MOV A,#10H
……
ORG 2000H
SECOND: CLR A
第1条定位伪指令指定了标号START的地址为1000H,“MOV A,#10H”指令及其后面的指令汇编成的机器码放在从1000H开始的存储单元中。
第2条定位伪指令指定了标号SECOND的地址为2000H。从START开始的程序段所占用的存储地址最多为1FFFH,否则与从SECOND开始的程序段地址重叠,程序在编译时不会发生错误,但在运行时就会发生错误。
(2)DB定义字节伪指令
格式:标号:DB X1,X2,…,Xn
标号可有可无,Xi是单字节数据,它可为十进制数或十六进制数,可以为一个表达式,也可以是在括在引号‘’中的字符串,表示ASCII码的字符,两个数据之间用逗号“,”分开。它通知汇编程序从当前ROM地址开始,保留存储单元,并存入DB后面的数据。
例如下面的代码。
ORG 1000H
DB 0AAH
SDATA: DB 25,25H
经汇编后,从地址1000H处的存储器的内容如下:
(1000H)=AAH
(1001H)=19H
(1002H)=25H
(3)DW定义字伪指令
格式:标号:DW Y1,Y2,…,Yn
标号可有可无,Yi是双字节数据,它可为十进制数或十六进制数,可以为一个表达式,两个数据之间用逗号“,”分开。
它通知汇编程序从当前ROM地址开始,保留存储单元,并存入DW后面的数据。存放时高8位在前,低8位在后,如下所示。
ORG 1000H
DW 1234H
DW 2000
经汇编后,从地址1000H处的存储器的内容如下:
(1000H)=12H
(1001H)=34H
(1002H)=07H
(1003H)=D0H
(4)EQU赋值伪指令
格式:字符名称 EQU 项(数或汇编符号)
EQU伪指令是把“项”赋给“字符名称”,需要注意的是,这里的字符名称不同于标号(其后面没有冒号),但它是必需的,其中的项可以是数也可以是汇编符号。
用EQU赋过值的符号名称必须先定义后使用,这些被定义的字符名称可以用做数据地址、代码地址、位地址或一个立即数。因此它可以是8位的,也可以是16位的。
例如下面的代码。
AA EQU R1
MOV A, AA
这里AA就代表了工作寄存器R1。
(5)DATA数据地址赋值命令
格式:字符名称 DATA 数据或表达式
此命令把数据地址或代码地址赋予标号段规定的字符名称。被定义的字符名称也可以先使用后定义。
例如下面的代码。
ORG 8000H
INDEXJ DATA 8096H
LJMP INDEXJ
等价于如下代码。
ORG 8000H
LJMP 8096H
DATA和EQU的区别在于用DATA定义的字符名称作为标号登记在符号表中,故可先使用后定义;而用EQU定义的字符名称必须先定义后使用,其原因是EQU不定义在符号表中。
(6)DS定义存储空间伪指令
在汇编时,从指令地址开始保留DS之后表达式的值所规定的存储单元。
例如下面的代码。
ORG 1000H
DS 07H
DB 20H, 20
DW 12H
经汇编后,从地址1000H开始保留7个单元,然后从1007H处存储器的内容如下:
(1007H)=20H
(1008H)=14H
(1009H)=00H
(100AH)=12H
DB、DW、DS伪指令都只对程序存储器起作用,它们不能对数据存储器进行初始化。
(7)BIT定义位符号伪指令
格式:字符名称 BIT 位地址
这里的字符名称与标号不同,但它是必需的,其功能是把BIT之后的位地址赋给字符名称。
例如下面的代码。
P11 BIT P1.1
这样,P1口的位1地址91H就赋给了P1.1。
(8)END汇编结束伪指令
END伪指令通知汇编程序结束汇编,在END之后即使还有指令,汇编程序也不做处理。在程序中可以有多条END指令,一般在程序的最后需要一条END伪指令,否则汇编程序会提示警告错误。当然这不会影响程序的正常执行。
这组伪指令是用的比较多的,你可以简单理解为 if.........else语句,成立则运行,这里的成立就是编译响应的代码。
如果你学会了使用这些伪指令相信你在编程中会更加简洁,调试维护程序也很方便。