按所占字节分,分三种:
(1)单字节指令49条;
(2)双字节指令45条;
(3)三字节指令17条。
按执行时间来分,分三种:
(1)1个机器周期(12个时钟振荡周期)的指令64条;
(2)2个机器周期指令45条;
(3)4个机器周期——乘、除指令。
12MHz晶振,每个机器周期为1µs。
AT89S52一大特点是在硬件结构中有一个位处理机,一个处理位变量的指令子集。
2、指令格式
指令通常由两部分组成:操作码和操作数。
操作码——指令进行什么操作。
操作数——指令操作的对象。可能是一具体数据,也可能是指出到哪里取得数据的地址或符号。
1)单字节指令:操作码和操作数同在一个字节中。
(2)双字节指令:一个字节为操作码,另一个字节是操作数。
(3)三字节指令:操作码占一个字节,操作数占二个字节。
3、指令系统的寻址方式
寄存器寻址方式:
指令中的操作数为某一寄存器的内容。
例如:MOV A,Rn ;(Rn)→A,n =0~7
把Rn中的源操作数送入到累加器A中。由于指令指定了从寄存器Rn中取得源操作数,所以称为寄存器寻址方式。
直接寻址方式:
指令中直接给出操作数的单元地址,该单元地址中的内容就是操作数,直接的操作数单元地址用“direct”表示。
例如: MOV A,direct
“direct”就是操作数的单元地址。
例如: MOV A,40H
表示把内部RAM 40H单元(direct)的内容传送到A。指令中源操作数(右边的操作数)采用的是直接寻址方式。
指令中两个操作数都可由直接寻址方式给出。
例如: MOV direct1, direct2
具体指令:MOV 42H,62H
把片内RAM中62H单元的内容送到片内RAM中的42H单元中。
直接寻址是访问片内所有特殊功能寄存器的唯一寻址方式。
寄存器间接寻址方式:
寄存器中存的是操作数地址,即先从寄存器中找到操作数的地址,再按该地址找到操作数。
为了区别寄存器寻址和寄存器间接寻址,在寄存器间接寻址方式中,应在寄存器名称前面加前缀标志“@”。
例如:MOV A,@Ri ;i=0或1
其中, Ri的内容为40H,即把内部RAM 40H地址单元中的内容传送给A。
立即数寻址方式:
直接在指令中给出操作数——也称立即数。为了与直接寻址指令中的直接地址加以区别,需在操作数前加前缀标志“#”。
例如: MOV A,#40H
第一个字节是操作码,第二字节是立即数,就是放在程序存储器内的常数
基址寄存器加变址寄存器间址寻址方式:
以DPTR或PC作为基址寄存器,以累加器A作为变址寄存器,以两者内容相加形成的16位地址作为目的地址进行寻址。例如指令: MOVC A,@A+DPTR
其中,(A)=05H,(DPTR)=0400H,指令执行结果是把程序存储器0405H单元的内容传送给A。
本寻址方式的指令有3条:
MOVC A,@A+DPTR
MOVC A,@A+PC
JMP A,@A+DPTR
相对寻址方式:
解决程序转移。该寻址是以该转移指令的地址(PC值)加上它的字节数,再加上相对偏移量(rel),形成新的转移目的地址,从而程序转移到该目的地址。转移的目的地址用下式计算:
目的地址=转移指令所在的地址+转移指令字节数+rel
其中,偏移量rel是带符号8位二进制补码数,–128~+127。
程序转移范围是以转移指令的下条指令首地址为基准地址,相对偏移在–128~+127之间。
例如, SJMP rel
程序要转移到该指令的PC值加3再加上rel的目的地址处。编写程序时,只需在转移指令中直接写要转向的地址标号。
例如: SJMP LOOP
“LOOP” 为目的地址标号。汇编时,由汇编程序自动计算和填入偏移量。但手工汇编时,偏移量的值由手工计算。
位寻址方式:
对内部RAM和特殊功能寄存器具有位寻址功能的某位内容进行置1和清0操作。
位地址一般以直接位地址给出,位地址符号为“bit”。
例如:MOV C,bit 其具体指令: MOV C,40H
把位地址为40H的值送到进位位C。
由于AT89S52具有位处理功能,可直接对数据位方便地实现置1、清0、求反、传送、判跳和逻辑运算等操作,为测控系统的应用提供了最佳代码和速度,增强了实时性。
4、8051指令系统分类介绍
数据传送类指令:
使用最频繁。一般数据传送类指令的助记符为“MOV”,通用格式如下:
MOV <目的操作数>,<源操作数>
数据传送类指令是把源操作数传送到目的操作数。指令执行之后,源操作数不改变,目的操作数修改为源操作数。所以数据传送类操作属“复制”性质,而不是“搬家”。
本类指令不影响标志位:Cy、Ac和OV,但不包括奇偶标志位P。
(1)以累加器为目的操作数的指令
MOV A,Rn ; (Rn)→A,n =0~7
MOV A,@ Ri ; ((Ri))→A i =0,1
MOV A,direct ; (direct)→A
MOV A,#data ; #data→A
把源操作数内容送累加器A,源操作数有寄存器寻址、直接寻址、间接寻址和立即数寻址等方式,例如:
MOV A,R6 ;(R6)→A,寄存器寻址
MOV A,@R0 ;((R0))→A,间接寻址
MOV A,70H ;(70H)→A,直接寻址
MOV A,#78H ;78H→A,立即数寻址
(2)以Rn为目的操作数的指令
MOV Rn ,A ;(A)→Rn ,n =0~7
MOV Rn ,direct ;(direct)→Rn ,n =0~7
MOV Rn ,#data ;#data→Rn ,n =0~7
把源操作数送入当前寄存器区的R0~R7中的某一寄存器。
(3)以直接地址direct为目的操作数的指令
MOV direct,A ; (A)→direct
MOV direct,Rn ; (Rn)→direct,n =0~7
MOV direct1,direct2 ;(direct2)→direct1
MOV direct,@Ri ; ((Ri))→direct,i =0,1
MOV direct,#data ; #data→direct
(4)以寄存器间接地址为目的操作数的指令
MOV @Ri,A ;(A)→((Ri)), i=0,1
MOV @Ri,direct ;(direct)→((Ri)),i=0,1
MOV @Ri,#data ;#data→((Ri)), i=0,1
功能是把源操作数内容送入R0或R1指定的存储单元中。
(5)16位数传送指令
MOV DPTR,#data16;#data16→DPTR
功能是把16位立即数送入DPTR,用来设置数据存储器的地址指针。
AT89S52有两个DPTR,通过设置特殊功能寄存器AUXR1中的DPS位来选择。当DPS=1,则指令中的DPTR即为DPTR1,DPTR0被屏蔽,反之亦然。
DPTR为16位的数据指针,分为DPH和DPL。操作十分灵活方便。设有两个DPTR后,就可避免频繁的出入堆栈操作。
对于所有MOV类指令,累加器A是一个特别重要的8位寄存器,CPU对它具有其他寄存器所没有的操作指令。后面将要介绍的加、减、乘、除指令都是以A作为目的操作数。
Rn为所选择的寄存器组中的R0~R7,直接地址direct为内部RAM的00H~7FH和特殊功能寄存器(地址范围80H~FFH)
在间接地址中,用R0或R1作为内部RAM的地址指针,可访问内部RAM的00H~7FH共128个单元。
(6)堆栈操作指令
内部RAM中设定一个后进先出(LIFO,Last In First Out)的区域,称为堆栈。在特殊功能寄存器中有一个堆栈指针SP,指示堆栈的栈顶位置。堆栈操作有进栈和出栈两种,因此,在指令系统中相应有两条堆栈操作指令。
(7)进栈指令
PUSH direct
首先将栈指针SP加1,然后把direct中的内容送到SP指示的内部RAM单元中。
例如:当(SP)=60H,(A)=30H,(B)=70H时,执行下列指令
PUSH Acc ;(SP)+1=61H→SP,(A)→61H
PUSH B ;(SP)+1=62H→SP,(B)→62H
结果:(61H)=30H,(62H)=70H,(SP)=62H。
(8)出栈指令
POP direct
将SP指示的栈顶单元的内容送入direct字节中,SP减1。
例如:当(SP)=62H,(62H)=70H,(61H)=30H时,执行指令
POP DPH ;((SP))→DPH,(SP)-1→SP
POP DPL ;((SP))→DPL,(SP)-1→SP
结果为(DPTR)=7030H,(SP)=60H。
(8)累加器A与外部数据存储器RAM/IO传送指令
MOVX A,@DPTR ;((DPTR))→A,读外部RAM/IO
MOVX A,@Ri ;((Ri))→A,读外部RAM/IO
MOVX @DPTR,A ;(A)→((DPTR)),写外部RAM/IO
MOVX @Ri ,A ;(A)→((Ri)),写外部RAM/IO
算术运算类指令
(1)加法指令
4条指令:
ADD A,Rn ;(A)+(Rn)→A ,n=0~7
ADD A,direct ;(A)+(direct)→A
ADD A,@Ri ;(A)+((Ri))→A,i=0,1
ADD A,#data ;(A)+#data→A
8位加法指令的一个加数总是来自累加器A,而另一个加数可由寄存器寻址、直接寻址、寄存器间接寻址和立即数寻址等不同的寻址方式得到。加的结果总是放在累加器A中。
使用本指令时,要注意累加器A中的运算结果对各个标志位的影响:
(1)如果位7有进位,则进位标志Cy置1,否则Cy清0。
(2)如果位3有进位,辅助进位标志Ac置1,否则Ac(Ac为PSW寄存器中的一位)清0。
(3)如果位6有进位,而位7没有进位,或者位7有进位,而位6没有进位,则溢出标志位OV置1,否则OV清0。
溢出标志位OV的状态,只有带符号数加法运算时才有意义。当两个带符号数相加时,OV=1,表示加法运算超出了累加器A所能表示的带符号数的有效范围(-128~+127),即产生了溢出,表示运算结果是错误的,否则运算是正确的,即无溢出产生。
(2)带进位加法指令
特点是进位标志位Cy参加运算,三个数相加。 4条指令:
ADDC A,Rn ;(A)+(Rn)+C→A ,n =0~7
ADDC A,direct ;(A)+(direct)+C→A
ADDC A,@Ri ;(A)+((Ri))+C→A,i =0,1
ADDC A,#data ;(A)+#data+C→A
如果位7有进位,则进位标志Cy置“1”,否则Cy清“0”;
如果位3有进位,则辅助进位标志Ac置“1”,否则Ac清“0”;
如果位6有进位而位7没有进位,或者位7有进位而位6没有进位,则溢出标志OV置“1”,否则标志OV清“0”。
(3)增1指令
5条指令:
INC A
INC Rn ;n=0~7
INC direct
INC @Ri ;i =0,1
INC DPTR
把指令中所指出的变量增1,且不影响PSW中的任何标志。
指令“INC DPTR”,16位数增1指令。首先对低8位指针DPL执行加1,当溢出时,就对DPH的内容进行加1,不影响标志Cy。
(4)十进制调整指令
用于对BCD码加法运算结果的内容修正,指令格式为: DA A
是对压缩的BCD码(一个字节存放2位BCD码)的加法结果进行十进制调整。
两个BCD码按二进制相加之后,必须经本指令的调整才能得到正确的压缩BCD码的和数。
(5)带借位的减法指令
4条指令:
SUBB A,Rn ; (A)-(Rn)-Cy→A,n =0~7
SUBB A,direct ; (A)-(direct)-Cy→A
SUBB A,@Ri ; (A)-((Ri))-Cy→A, i =0,1
SUBB A,#data ; (A)-#data-Cy→A
从A的内容减去指定变量和进位标志Cy的值,结果存在A中。
如果位7需借位则Cy置1,否则Cy清0;
如果位3需借位则Ac置1,否则Ac清0;
如果位6借位而位7不借位,或者位7借位而位6不借位,则溢出标志位OV置“1”,否则OV清“0”。
控制转移类指令
1.长转移指令
LJMP addr16
指令执行时,把转移的目的地址,即指令的第二和第三字节分别装入PC的高位和低位字节中,无条件地转向addr16指定的目的地址:64KB程序存储器地址空间的任何位置。
2.相对转移指令
SJMP rel
无条件转移,rel为相对偏移量,是一单字节的带符号8位二进制补码数,因此程序转移是双向的。rel如为正,向地址增大的方向转移;rel如为负,向地址减小的方向转移。
3.绝对转移指令
AJMP addr11
4.间接跳转指令
JMP @A+DPTR
单字节转移指令,目的地址由A中8位无符号数与DPTR的16位无符号数内容之和来确定。以DPTR内容为基址,A的内容作为变址。给A赋予不同值,即可实现多分支转移。
5.条件转移指令
执行指令时,如条件满足,则转移;不满足,则顺序执行下一指令。转移目的地址在以下一条指令首地址为中心的256B范围内(-128~+127)。
JZ rel ;如果累加器内容为0,则执行转移
JNZ rel ;如果累加器内容非0,则执行转移
6.比较不相等转移指令
CJNE A,direct,rel
CJNE A,#data,rel
CJNE Rn,#data,rel
CJNE @Ri,#data,rel
7.减1不为0转移指令
把减1与条件转移两种功能合在一起。两条:
DJNZ Rn,rel ;n =0~7
DJNZ direct,rel