[6].
累加器A与片外数据存储器RAM传送指令(4条) 这4条指令的作用是累加器A与片外RAM间的数据传送。使用寄存器寻址方式:MOVX @DPTR,A ;(A)→((DPTR)) 累加器中的内容送到数据指针指向片外RAM地址中MOVX A, @DPTR ;((DPTR))→(A) 数据指针指向片外RAM地址中的内容送到累加器A中MOVX A, @Ri ;((Ri))→(A) 寄存器Ri指向片外RAM地址中的内容送到累加器A中MOVX @Ri,A ;(A)→((Ri)) 累加器中的内容送到寄存器Ri指向片外RAM地址中 说明:1、在89C51中,与外部存储器RAM打交道的只可以是累加器A,所有需要送入外部RAM的数据必须要通过A送出去。而所有要读入外部RAM中的数据也必需要通过A读入。在此我们可以看出外部RAM的区别了。内部RAM间可以直接进行数据传递,而外部则不行。比如,要将外部RAM中某单元(设为110H单元的数据)送入另外一个单元(设为200H单元),也必须要先将110H单元中的内容读入A,然后再送入200H单元中去。 2、要读写外部的RAM,当然也必须要先知道RAM的地址,在后两条指令中,地址是被地址放在DPTR中的,而前两条指令,由于Ri(即R0或R1)只是一个8位的寄存器,所以只能提供低8位地址,因为有时扩展的外部RAM的数量比较少,少于或等于256个,就只需提供8位地址就足够了。请大家再复习下我们前面《51单片机的寻址方式》这节课。 3、使用时应当首先将要读或写的地址送入DPTR或Ri中,然后再用读写命令。例:将外部RAM中100H单元中的内容送入外部RAM中200H单元中。 MOV DPTR,#0100H MOVX A,@DPTR MOV DPTR,#0200H MOVX @DPTR,A
[7].
堆栈操作类指令(2条) 这4类指令的作用是把直接寻址单元的内容传送到堆栈指针SP所指的单元中,以及把SP所指单元的内容送到直接寻址单元中。这类指令只有两条,下述的第一条常称为入栈操作指令,第二条称为出栈操作指令。需要指出的是,单片机开机复位后,(SP)默认为07H,但一般都需要重新赋值,设置新的SP首址。入栈的第一个数据必须存放于SP+1所指存储单元,故实际的堆栈底为SP+1所指的存储单元。PUSH data ;(SP)+1→(SP),(data)→(SP) 堆栈指针首先加1,直接寻址单元中的数据送到堆栈指针SP所指的单元中POP data ;(SP)→(data)(SP)-1→(SP), 堆栈指针SP所指的单元数据送到直接寻址单元中,堆栈指针SP再进行减1操作 第一条指令称为推入,就是将direct中的内容送入堆栈中,第二条指令称为弹出,就是将堆栈中的内容送回到direct中,推入指令的执行过程是:首先将P中的值加1,然后把SP中的值当做地址,将direct中的值送入以SP中的值为地址的RAM单元中去。例: MOV SP,#5FH MOV A,#100 MOV B,#20 PUSH ACC PUSH B 执行第一条PUSH ACC指令是这样的:将SP中的值加1,即变为60H,然后将A中的值送到60H单元中,因此执行完本条指令后,内存60H单元中的值就是100,同样执行PUSH B时,是将SP+1,即变为61H,然后将B中的值送入到61H单元中,即执行完本条指令后61H单元中的值变为20。 POP指令的执行也是这样的,首先将SP中的值做为地址,并将此地址中的数送到POP指令的那个direct中,然后SP减1。接上例: POP B POP ACC 则执行过程是:将SP中的值(现在是61H)作为地址,取61H单元中的数值(现在是20),送到B中,所以执行完本条指令后B中的值是20,然后SP减1,因此本条指令执行完后,SP的值变为60H,然后搪行POP ACC,将SP中的值(60H)作为地址,从该地址中取数(现在是100),并送到ACC中,所以执行完本条指令后,ACC中的值是100。这有什么意义呢?ACC中的值本来就是100,B中的值本来就是20,是的,在本例中,的确没有意义,但在实际工作中,则在PUSH B后往事要执行其它的指令,而且这些指令会把A中的值,B中的值改掉,所以在程序结束,如果我们要把A和B中的值恢复原值,那么这些指令就没有意义了。还有一个问题,如果我们不用堆栈,比如说在PUSH ACC指令处用MOV 60H,A在PUSH B处用指令MOV 61H,B,然后用MOV A,60H,MOV B,61H来替代两处POP指令,不也是一样吗?是的,从结果上看是一样的,但从过程看是不一样的,PUSH和POP指令都是单字节,单周期指令,而MOV指令则是双字节,双周期指令,更何况,堆栈的作用不止于此,所以一般的计算机上都设有堆栈,而我们在编写子程序,需要保存数据时,通常不采用后面的方法,而是用堆栈的方法来实现。例:写出以下程序的运行结果 MOV 30H,#12 MOV 31H,#23 PUSH 30H PUSH 31H POP 30H POP 31H 结果是30H中的值变为23,而31H中的值则变为12。也就是两者进行了数据交换。从这个例子可以看出:使用堆栈时,入栈的书写顺序和出栈的书写顺序必须相反,才能保证数据被送回原位,否则就出错了。另外特别注意事项:进行堆栈操作时,我们不能: PUSH R0 PUSH R1 而只能: PUSH 00H PUSH 01H POP也是一样。 [8].
交换指令(5条) 这5条指令的功能是把累加器A中的内容与源操作数所指的数据相互交换。XCH A,Rn ;(A)←→(Rn)累加器与工作寄存器Rn中的内容互换XCH A,@Ri ;(A)←→((Ri))累加器与工作寄存器Ri所指的存储单元中的内容互换XCH A,data ;(A)←→(data)累加器与直接地址单元中的内容互换XCHD A,@Ri ;(A3-0)←→((Ri)3-0)累加器与工作寄存器Ri所指的存储单元中的内容低半字节互换SWAP A ;(A3-0)←→(A7-4)累加器中的内容高低半字节互换
[9].
16位数据传送指令(1条) 这是89C51单片机唯一的一条16位立即数传递指令,其功能是将一个16位的立即数送入数据指针DPTR中去。其中高8位送入DPH,低8位送入DPL。MOV DPTR,#data16 ;#dataH→(DPH),#dataL→(DPL)16位常数的高8位送到DPH,低8位送到DPL 例如:MOV DPTR,#2345 则执行完程序后,DPL中的值为23,DPL中的值为45。 |