
3.2 寻址方式概述
所谓寻址方式,通俗地说就是CPU寻找操作数地址的方式。寻址的“址”是指操作数的地址。绝大多数指令执行时都需要操作数,因此也就存在着到哪里去取得操作数的问题。在计算中只要给出单元地址,就能得到所需要的操作数,因此,寻址方式其实质就是如何找到操作数的地址。
根据指令操作的需要,计算机总是提供多种寻址方式。一般来说,寻址方式越多,计算机的寻址能力就越强,但是指令系统也就越加复杂。寻址方式与计算机的存储器空间结构是密切联系的,AT89S51/52单片机共有7种寻址方式。
3.2.1 描述操作数的简记符号
在介绍寻址方式和指令之前,先把指令中使用的符号表示的意义做简单说明。
Rn:表示当前工作寄存器组的8个通用寄存器R0~R7,所以n=0~7。它在片内数据存储器中的地址由PSW中RS1、RS0确定,可以是00H~07H(第0组)、08H~0FH(第1组)、10H~17H(第2组)、18H~1FH(第3组)。
Ri:表示当前工作寄存器组中可作为地址指针的两个工作寄存器R0、R1。可用作间接寻址的寄存器,只能是R0、R1两个寄存器,所以i=0,1。
#data:表示8位立即数,即包含在指令中的8位常数。
#data16:表示16位立即数,即包含在指令中的16位常数。
addr16:表示16位目的地址,只限于在LCALL和LJMP指令中使用。目的地址的范围是64KB程序存储器地址空间。
addr11:表示11位目的地址,只限于在ACALL和AJMP指令中使用。目的地址必须放在与下一条指令第一个字节同一个2KB程序存储器地址空间之内。
re1:表示相对转移指令中的偏移量,为8位带符号补码数。它表示相对跳转的偏移字节,用于相对转移指令中。偏移量以下一条指令第一字节地址为基值,偏移范围为-128~+127。
DPTR:表示数据指针寄存器。
bit:表示内部RAM(包括特殊功能寄存器)中的直接寻址位。
ACC:表示直接寻址方式的累加器。
C或CY:表示进位标志位,它也是位处理机的累加位。
@:表示间址寄存器的前缀标志。
/:加在位地址的前面,表示对该位状态取反。
(X):表示某寄存器或某单元的内容。
((X)):表示由X间接寻址的单元中的内容。
←:表示箭头左边的内容被箭头右边的内容所取代。
direct:表示内部RAM的8位直接地址,既可以是内部RAM的低128个单元地址,也可以是特殊功能寄存器的单元地址或符号。因此在指令中direct表示直接寻址方式。寻址范围为256个单元。其值包括0~127(内部RAM低128单元地址)和128~255(特殊功能寄存器的单元地址或符号)。
SP:表示堆栈指针。
3.2.2 寻址方式
所谓寻址方式就是如何指定操作数或其所在单元。根据指定方法的不同,AT89S51/52单片机共有立即寻址、寄存器寻址、直接寻址、寄存器间接寻址、位寻址、变址寻址和相对寻址等7种寻址方式,下面分别予以介绍。
1.立即寻址方式
立即寻址是指在指令中直接给出参加运算的操作数。为了与直接寻址指令中的直接地址相区别,在操作数前面加上“#”号表示,又称为立即数。立即数就是存储在程序存储器中的常数,一般为8位。
例如,指令MOV A,#3AH。
这条指令表示将立即数3AH送入累加器A中。其中源操作数#3AH就是立即数,采用立即寻址,如图3-1所示。
图3-1 立即寻址方式示意图
在AT89S51/52单片机的指令系统中,还有一条含16位立即数寻址的指令“MOV DPTR,#data16”。
例如,指令MOV DPTR,#3AEFH。
这条指令表示将16位立即数#3AEFH送入地址指针DPTR中,其中高8位送入DPH,低8位送入DPL。
2.寄存器寻址方式
寄存器寻址就是指操作数存储在所选定的寄存器中。这些寄存器包括通用工作寄存器组R0~R7、累加器A、通用寄存器B和地址寄存器DPTR等。寄存器寻址方式的指令中以符号名称来表示寄存器。
例如,指令MOV A,R3。
这条指令的功能是把寄存器R3的内容传送到累加器A中。源操作数R3和目的操作数A都采用寄存器寻址,如图3-2所示。
图3-2 寄存器寻址方式示意图
3.直接寻址方式
在这种寻址方式中,指令中参加运算的操作数直接以单元地址的形式给出。在AT89S51/52单片机中,直接地址只能用来寻址内部数据存储器低128单元和特殊功能寄存器,即内部RAM。
例如,指令MOV A,30H。
其功能是把内部RAM30H单元中的数据传送给累加器A。其中30H就是内部数据存储器的单元地址,如图3-3所示。
图3-3 直接寻址方式示意图
对于特殊功能寄存器只能用直接寻址的方式来访问,除可以用单元地址形式给出外,还可以用寄存器符号形式给出。
例如,指令MOV P3,30H与指令MOV 0B0H,30H。
这两条指令都是将内部RAM30H单元中的数据传送给特殊功能寄存器P3,其中B0H为P3的单元地址,在前面加0是为了和标号区分开来。对于以英文字母开头的十六进制数都应该在字母前加0,指示其为一个数值。源操作数30H与目的操作数P3、0B0H都是采用直接寻址的方式。
4.寄存器间接寻址方式
寄存器间接寻址的特点是寄存器中存储的数值不是操作数,而是操作数的地址,寄存器称为间接寻址寄存器。这种寻址方式可用于访问片内数据存储器或片外数据存储器。
当访问片内RAM低128B或片外RAM低256B时,可采用当前工作寄存器组中的R0或R1作间接寻址寄存器,为了与寄存器寻址区别,用@Ri表示(i=0或1)。即由R0或R1作为地址指针,间接给出操作数所在的地址。
当访问外部RAM整个64KB范围时(包括片外RAM低256B),只能使用DPTR作间接寻址寄存器,其形式为@DPTR。
此外,对于堆栈操作指令(PUSH和POP)也应算作是寄存器间接寻址,即以堆栈指针(SP)作间址寄存器的间接寻址方式。
寄存器寻址方式,寄存器中存储的是操作数。而寄存器间接寻址方式,寄存器中存储的则是操作数的地址,即操作数是通过寄存器间接得到的,因此称为寄存器间接寻址。这两种寻址方式是要区分开的。
例如,指令MOV A,@R0,假定R0工作寄存器的内容是3AH,直接地址3AH中的内容为4AH,即(R0)=3AH,(3AH)=4AH。
这条指令的功能是以当前工作寄存器R0中内容(3AH)作为地址,将3AH单元的内容(4AH)取出来送到累加器A中。源操作数@R0采用寄存器间接寻址,如图3-4所示。
图3-4 寄存器间接寻址方式示意图
指令执行后结果为(A)=4AH。
5.位寻址方式
位寻址是指对片内数据存储器的位寻址区和某些可位寻址的特殊功能寄存器中的二进制位进行位运算时的寻址方式。AT89S51/52单片机具有位处理功能,可以对二进制数据位进行操作,因此就有相应的位寻址方式。在进行位运算时,用进位位C作为累加器。操作数直接给出该位的地址,然后根据操作码的性质对其进行位运算。位地址与直接寻址中的字节地址形式完全一样,主要由操作码和操作数C进行区分,使用时须予以注意。
例如,指令MOV C,30H。
这条指令的功能是将位地址30H中的内容传送给位累加器C。位地址30H位于内部数据存储器字节26H的第0位(26H.0)。源操作数与目的操作数都是采用位寻址,如图3-5所示。
图3-5 位寻址方式示意图
位寻址的寻址范围包括内部RAM中的位寻址区和特殊功能寄存器的可寻址位。位寻址区所在单元地址为内部数据存储器20H~2FH,共16个单元,128个位,对这128个位的寻址使用直接位地址表示,位地址为00H~7FH(详见表2-6)。特殊功能寄存器的可寻址位是指可供位寻址的特殊功能寄存器,共有11个可位寻址的特殊功能寄存器,实有可寻址位83个。对这些位地址在指令中有如下4种表示方法:
1)直接使用位地址。这些位地址已在表2-6与表2-7中列出。例如,P1口第5位的地址为95H。
2)位名称表示方法。特殊功能寄存器中的一些寻址位是有符号名称的,例如,程序状态字PSW第1位是F1标志位,则可使用F1表示该位。
3)单元地址加位的表示方法。例如,95H单元(即特殊功能寄存器P1)的第5位,表示为95H.5。
4)特殊功能寄存器符号加位的表示方法。例如,寄存器P1的第5位,表示为P1.5。
除此之外,还可以采用伪指令BIT进行自定义的方法表示位。这些不同的寻址位表示方法,将为用户程序设计带来方便。
6.变址寻址方式
AT89S51/52单片机的变址寻址是以DPTR或PC作为基址寄存器,以累加器A作为变址寄存器,变址寻址时,把两者的内容相加,所得到的结果作为操作数的地址。这种方式常用于查表操作,用于访问程序存储器。
例如,指令MOVC A,@A+DPTR,假定指令执行前(A)=78H,(DPTR)=2356H,(23CE)=74H。
这条指令的功能是把DPTR和A的内容相加,将相加内容作为程序存储器的地址,再把所得到的程序存储器地址单元的内容送累加器A。
变址寻址形成的操作数地址为2356H+78H=23CEH,而23CE单元的内容为74H,故该指令执行结果是A的内容为74H,即指令执行结果为(A)=74H,如图3-6所示。
图3-6 变址寻址方式示意图
变址寻址方式只能对程序存储器进行寻址,它是专门针对程序存储器的寻址方式,寻址范围可达64KB。
变址寻址的指令只有3条:
MOVC A,@A+DPTR
MOVC A,@A+PC
JMP @A+DPTR
其中前两条是针对程序存储器的读指令,后一条则是无条件转移指令。尽管变址寻址方式较为复杂,但变址寻址的指令却都是一字节指令。
7.相对寻址方式
相对寻址方式是为实现程序的相对转移而设计的,为相对转移指令所采用。在相对寻址的转移指令中,给出了地址偏移量,把PC的当前值加上偏移量就构成了程序转移的目的地址。但这里的PC当前值是指执行完该条转移指令后的PC值,即转移指令的PC值加上该指令的字节数。因此转移的目的地址可用如下公式表示:目的地址=转移指令地址+转移指令字节数+re1。偏移量re1是一个带符号的8位二进制补码数,所能表示的数的范围是-128~+127,因此相对转移是以转移指令所在地址为基点,向前最大可转移(127+转移指令字节数)个单元地址,向后最大可转移(128-转移指令字节数)个单元地址。在编程时偏移量的值可以直接用数字量,也可以用标号表示。通常采用地址标号表示,汇编程序可以自动计算出目的地址。