但当页面之间跳转(GOTO CALL指令)必须先把f3的PA0、PA1设置为相应的页面。需要注意的是:在系统复位时,程序计数器PC将指向程序存储器最后一个页面的最后一个单元。例如PIC16C54/55指向1FFH,PIC16C56指向3FFH,PIC16C57/58则指向7FFH。状态寄存器f3的PA0、PA1指向零页空间,所以程序员在编程时需要在程序存储器底部放置一条跳转指令,跳到程序入口。
单片机执行程序时,程序计数器(PC)自动加1,程序操作支持直接、间接、相对寻址方式,能由测试、跳转指令、子程序调用指令、转移指令或把算出的地址装入PC来实现程序的跳转。片内两级堆栈为子程序嵌套提供服务。
堆栈 PIC16C5X系列单片机提供两级堆栈,参考上图。CALL指令把程序计数器加1压入堆栈1,栈1自动压入栈2,当多于两级子程序调用指令执行时,堆栈中只有存储最近两个返回地址,所以主程序中调用的子程序最多只能嵌套一次,当执行一条CALL指令,PIC16C56/57/58的f3之页面选择位PA1、PA0被装入程序计数器的最高两位,第9位清“0”,也就是子程序入口地址必须位于存储页的低半页000-0FF、200-2FF、400-4FF、600-6FF地址。但这里指的是子程序主体的起始位置,而子程序体是可以延伸到下半页面的。 PIC16C56/57/58,由于程序空间分别为1k和2k,可能存在跨页面子程序调用,所以调用子程序前须先把f3的PA1、PA0设置成该子程序所在页面地址。诚然,如果子程序与调用程序同在一个页面,则无需这个步骤。由于堆栈和PC的宽度是一样的,所以可在程序的任何地方执行CALL指令来调用子程序。当然跨页面的调用还须考虑页面地址PA1、PA0。 RETLW(子程序返回指令)把栈1内容送到程序计数器PC,同时栈2内容复制到栈1,多于两个RETLW指令运行时,栈1只会装入先前存在栈2的地址,对于PIC16C56/57,程序总是返回调用它的同一页面,不管它是处在哪个页面,也不管f3的页面选择位的设置状态如何。但是执行RETLW指令并不会改变f3中的PA1、PA0的值。w寄存器会被装入RETLW指令中所指向的数值,即立即数。这在程序存储器中实现数据查表时就非常有用。 |