11 寻址方式和指令系统一、寄存器1.1 工作寄存器有R0、R1、R2、R3、R4、R5、R6、R7共8个,都是8位的寄存器其中R0、R1可以做数据指针,可以做间接地址空间的数据指针,也可以做外部数据区的指针,以间接寻址的方式对RAM中的数据据进行读取当然,R0、R1也可以像R2、R3、R4、R5、R6、R7一样,做普通的寄存器来用在物理上,工作寄存器共有四组,分别占用内部RAM的00H~07H、08H~0FH、10H~17H、18H~1FH四组地址当前使用的通用寄存器组,是由程序状态字PSW的第四位和第三位(RS1、RS0)来决定的四组寄存器,在中断程序中,可以通过切换寄存器的方式,来快速实现现场保护在C51中,可以用using 0、using 1、 using 2、 using 3 来指明某函数所用的寄存器组如:Void int0pro(void) interrupt 0 using 2 //这个函数用第二组工 {………. //作寄存器 } 对通用寄存器的访问,是最快速的访问比下面的两条指令:MOV A,R7MOV A,07H都是将内部RAM空间的07H单元存储的数据,赋给寄存器A,但是前者是寄存器寻址,比后者直接寻址,更快一些。
1.2 累加器A寄存器A是一个特殊的寄存器,所有算术运算类指令中的一个操作数,必须在寄存器A中,其运算结果,也一定存入该寄存器由于加法是最基本的运算,所以称寄存器A为累加器,它是8051家族单片机所有的寄存器中最重要的一个如: ADD A,@R1 SUBB A,#23 MUL AB DIV AB累加器A不占用存储单元,有一个专门的硬件电路但是它可以映射到SFR空间,占用地址:0E0H,此时,写做ACC,在栈操作可以使用比较下面代码:MOV A,#0MOV ACC,#0虽然执行后的结果,没有区别,但是后者执行时间要长一倍1.3 辅助寄存器B寄存器B,用于乘除法的第二个操作数,运算的部分结果,也存在该寄存器中B是一个SFR,占用地址:0F0H1.4 程序状态字PSW程序状态字PSW,是一个SFR,来指明当前指令的执行情况、累加器A的数据状态、工作寄存器组的选择等F0、F1可做为普通的位变量来使用这个寄存器在运算类操作、条件转移、中断时寄存器组切换时,是非常有用的CY,也称C,在位传送指令中使用,如:MOV C,P2.0MOV P1.0,C1.5 数据指针DPTRDPTR是一个16位寄存器,也可当成两个8位寄存器DPH、DPL。
外部数据不能直接访问,必须通过数据指针DPTR或R0、R1来间接访问但是R0、R1的访问范围,只能限定在一页(256字节)内,限定在哪一页,由页寄存器EMI0CN来确定如:MOV EMI0CN, #12h ; 将地址的高字节装入 EMI0CNMOV R0, #34h ; 将地址的低字节装入 R0MOVX A, @R0 ; 将地址 0x1234 的内容装入累加器 以上三句,和下面两句是等价的:MOV DPTR,#1234MOVX A,@DPTR上面三句,好像并没有下面的两句简洁,但是如果我们在一页内频繁操作的话,页寄存器,并不需要重新赋值,这样,通过R0(R1)来对外部RAM进行访问,在速度上,就占优势了另一方面,我们也拥有三个指针指向外部数据区,在程序设计上,也会更加便利1.6 堆栈指针SPSP总是指向当前栈顶在每次执行 PUSH 操作前,堆栈指针加 1执行 POP操作后,堆栈指针减 1,SP 寄存器复位后,其值是07H,堆栈区占用第一组工作寄存器的位置,一般说来,这样是不能容忍的,须将SP重新赋给一个大于30H的值,使堆栈区不占用寄存器空间、也不占用位寻址空间。
我们常将SP赋于一个大于一个80H的值,使堆栈区位于间接寻址区,以释放更多的可直接寻址的RAM空间1.7 程序指针PC 程序当前的位置,PC的值不能由软件赋值,它根据程序指令情况自动变化我们可以用PC间址寻址,来读取存在程序空间的数据二、寻址方式所谓寻址方式,就是把操作数取出来的方式应该叫寻数方式2.1 寄存器寻址操作数在寄存器中如下列指令:INC R0INC DPTR2.2 立即寻址 操作数,是一个常数,如下列指令:MOV R0,#23HADD A,#34H2.3 直接寻址 操作数,在直接寻址空间,如下列指令:MOV A,30H;将直接寻址空间地址为30H的数据,传送到累加器AADD A,38H;将直接寻址空间地址为38H的数据,和累加器A的数据相加,结果存入累加器A2.4 间接寻址操作数,是用R0或R1指向的地址单元的数据如下列: MOV R0,#80HMOV A,@R0 ; 将间接寻址空间地址为80H的数据,传送到累加器AMOV R1,#40HMOV A,@R1 ; 将内部RAM空间地址为40H的数据,;传送到累加器A。
这部分区间,即可以直接寻址,也可以间接寻址 ADD A,@R1 ;内部RAM间接寻址的指针,只能是R0或R1 MOV DPTR,#0FFFH MOVX A, @DPTR ;外部RAM,地址为0XFFF的单元的数据,传给A MOV DPTR,#010000H MOVC A,@DPTR; 程序空间地址为0X1000的单元的数据,传给A2.5变址寻址这种寻址方式是以16位的程序计数器PC和数据指针DPTR作为基址,以8位的累加器A做为变址,两个寄存器的值相加,形成一个16位的地址,做为操作数的地址如:MOV A,#0MOVC A,@A+PCSJMP ADDR4TAB: 47H,48H,49H,4AH MOVC A,@A+DPTR2.6 相对寻址 SJMP LOOP ;相对转移指令2.7 位直接寻址对位空间进行寻址,该空间只能是直接寻址三、指令系统 8051共有 111条指令,也有人说有57条指令,统计口径不同3.1、数据传送类指令格式: MOV <目的字节>,<源字节>3.1.1 内部8位数据传送指令操作码目的源字节数执行时间(周期)MOVA#data21Data21@Ri11Rn11Rn#data21Data22A11Direct#data32Data32A21@Ri22Rn21@Ri#data21Data22A11如:MOV A,30H MOV A,R1 MOV A,@R1 MOV @R0,A MOV 30H,40H MOV 40H,80H MOV R1,#80H MOV P2,@R1 问题:MOV SP,#30H,在哪呢?3.1.2 位变量传送指令 MOV C,23HMOV BIT,00HMOV C,P1.03.1.3 16位数据传送指令 MOV DPTR,# data16;3.1.4 累加器与外部RAM的传送指令 MOVX A,@Ri MOVX @Ri,A MOVX @DPTR,AMOVX A,@DPTR3.1.5 查表指令 MOVC A,@A+PC MOVC A,@A+DPTR3.2 数据交换指令 XCH A,RnXCH A,@Ri //间接地址XCH A,direct //直接地址 XCHD A,@Ri //间接地址3.3 算术运算指令 3.3.1 加法指令 ADD A,RnADD A,directADD A,@RiADD A,#data3.3.2 带进位加法指令 ADDC A,RnADDC A,directADDC A,@RiADDC A,#data3.3.3 带借位减法 SUBB A,RnSUBB A,directSUBB A,@RiSUBB A,#data3.3.4 十进制调整DA A3.3.5 加一指令INC AINC RnINC directINC @RiINC DPTR3.3.6 减1指令DEC ADEC RnDEC directDEC @Ri3.4 逻辑运算类指令3.4.1 CLR A ;累加器A清零 CPL A ;累加器A取反 RL A ;累加器A移位 RR ARLC ARRC ASWAP A3.4.2逻辑运算ANL A,Rn ;逻辑与ANL A,directANL A,@RiANL A,#dataANL direct,AANL direct,#data 3.4.2逻辑或ORL A,Rn ;逻辑与ORL A,directORL A,@RiORL A,#dataORL direct,AORL direct,#data3.4.3 逻辑异或XRL A,Rn ;逻辑与XRL A,directXRL A,@RiXRL A,#dataXRL direct,AXRL direct,#data3.4.4 位操作指令CLR CCLR bitCPL CCPL bitSETB CSETB bit 3.4.5 位逻辑运算指令 ANL A,bit ANL A,/bit ORL A,bit ORL A,/bit3.5 转移指令3.5.1 无条件转移 LJMP addre16 AJMP addre11 SJMP rel JMP @A+DPTR3.5.2 条件转移 JZ relJNZ relJC relJNC relJB bit,relJNB bit,re。