首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

如何重新定位中断向量表

这条汇编指令采用的是PC变址相对间接寻址方式。它实际上以地址0xEFFE,EFFF中的数据为目的地址进行跳转。“,PCR”只表示它根据程序计数器PC的数据进行变址寻址。在本例中,我们将_Startup的地址值(0xC000)写入了映射矢量0xEFFE,EFFF中,则执行这个指令后,程序就跳转到0xC000处继续运行。

[此贴子已经被strongchen于2006-8-1 9:16:57编辑过]

海纳百川  有容乃大
在这个例子里,引导程序BOOT.C和应用程序MAIN.C是写在一个PROJECT里的。在实际的应用中,引导程序和应用程序可以同时由不同的组分别来做。生产时,可以先将BOOT程序写入芯片,然后在最后阶段将应用程序通过BOOT下载入芯片。
海纳百川  有容乃大

您的示例里中断地址影射很好,但我有点疑问。

您在boot.c文件的汇编里用的中断重影射地址指令是JMP而不是JSR,我不知道这地方是否有问题,能否请您做些解释。谢谢。
              非学无以广才,非志无以成学;              
关于这个问题,需要了解CPU进入及退出中断服务程序的过程。当中断发生后,CPU响应一个中断时,首先要将正在执行的程序地址保持到堆栈中(严格地说,应该是下一条指令的地址),然后将一些寄存器的内容,如CCR、A/B及X/Y寄存器,也压入栈,然后再到中断矢量中读取中断服务程序的入口地址,然后再从此地址开始执行指令。当退出中断服务程序时,要按序将堆栈中断的数据恢复到个寄存器中,再将保存在堆栈中的地址读回PC中,使程序回到中断前的程序中顺序执行。
所以,CPU响应中断的过程,应该是先入栈,再进中断服务程序,再出栈,再回到原程序。必须要有一组入栈和出栈的对应操作。
在我的例子程序中,当CPU响应中断时,会自动执行入栈的操作,然后读取的,还是原中断矢量区中的数据(如0xFFFC~0xFFFD),作为中断服务程序的入口地址。进入这个中断服务程序后,再跳转到另一个中断服务程序的入口,再执行真正的中断服务程序。这个真正的中断服务程序也是用interrupt的函数写的,因此它的最后一句指令是中断返回指令RTI。这样,当程序执行到这句指令时,就会进行出栈的操作。
由于这是中断函数而不是子函数,所以它的最后一句指令是RTI而不是RTS。也就是说,不能用JSR来调用。必须产生中断响应的过程,再跳转过来。
海纳百川  有容乃大
中断向量的重新映射与S12内部模块(寄存器、RAM和EEPRO)的映射是不同的。内部模块的映射是相应的通过寄存器,真正地改变这些模块的物理地址。而中断向量的物理地址实际上是不能改变的,我们将其重新映射,实际上是通过跳转指令,将其入口地址转向另一块数据区,即所谓的中断向量映射区。
海纳百川  有容乃大
非常感谢1
              非学无以广才,非志无以成学;              
16# strongchen
最近刚接触BOOTLOADER,一直困惑中断向量表重分配的方法,我用的是9S12HY128不像HY64支持IVBR中断向量表硬件重定位,只能采用您long long 之前自创的二次跳转方法,我想请教一下PCR具体代表什么含义,哪边能查到,还有请教以下的指令(AN4258 S12BOOTLOADER Main中)是什么含义,谢谢
#define __SEG_START_REF(a)  __SEG_START_ ## a
#define __SEG_END_REF(a)    __SEG_END_ ## a
#define __SEG_SIZE_REF(a)   __SEG_SIZE_ ## a
#define __SEG_START_DEF(a)  extern INT8 __SEG_START_REF (a) []
#define __SEG_END_DEF(a)    extern INT8 __SEG_END_REF   (a) []
#define __SEG_SIZE_DEF(a)   extern INT8 __SEG_SIZE_REF  (a) []

__SEG_START_DEF (RAM_CODE);
__SEG_END_DEF   (RAM_CODE);
__SEG_SIZE_DEF  (RAM_CODE);
返回列表