在dsPIC33上保存堆栈上下文会导致:由于未实现的FLASH内存访问而导致的陷阱

时间:2012-01-15 20:41:20

标签: assembly microchip mplab

我正在尝试保存寄存器的上下文并将堆栈指针存储到Assembly中的C变量,它可以工作,但是当它到达return语句时会抛出许多错误和崩溃。

以下是代码:

_saveContext:

    PUSH    SR                      
    PUSH    W0                      
    MOV     #32, W0
    MOV     W0, SR
    PUSH    W1                      
    PUSH.D  W2
    PUSH.D  W4
    PUSH.D  W6
    PUSH.D  W8
    PUSH.D  W10
    PUSH.D  W12
    PUSH    W14
    PUSH    RCOUNT
    PUSH    TBLPAG
    PUSH    ACCAL
    PUSH    ACCAH
    PUSH    ACCAU
    PUSH    ACCBL
    PUSH    ACCBH
    PUSH    ACCBU
    PUSH    DCOUNT
    PUSH    DOSTARTL
    PUSH    DOSTARTH
    PUSH    DOENDL
    PUSH    DOENDH                                                                                      
    PUSH    CORCON
    PUSH    PSVPAG
    MOV     W15, W0
    MOV     W0, _stackPointer  //Save to C Var
    RETURN

在MPLAB中模拟代码时,C变量会被赋予堆栈指针的值,但是当它到达RETURN时会导致多个错误:

“CORE-E0004:由于未执行的FLASH存储器访问导致的陷阱,发生在0xXXXXXX处的指令”错误

我认为这可能与我访问stackpointer(W15)的方式有关。

有人有什么建议吗?感谢

2 个答案:

答案 0 :(得分:0)

它正在崩溃,因为你试图返回到PSVPAG等于的任何东西,因为RETURN使用堆栈顶部的任何东西作为返回地址。如果没有先平衡堆栈,则无法从子例程返回。也就是说,在堆栈上保存上下文的想法似乎没有了,你为什么不使用普通的RAM?

答案 1 :(得分:0)

嗯,我找到了一个解决方法,我会在这里发布它可能会帮助其他人。

解决方案是直接将代码添加到我的C文件中并完全删除程序集文件。我只是在C:

中添加了一个程序集块,而不是调用程序集子程序
asm volatile("PUSH      SR          \n"
            "PUSH.D     W0          \n"                                 
            "PUSH.D     W2          \n"
            "PUSH.D     W4          \n"
            "PUSH.D     W6          \n"
            "PUSH.D     W8          \n"
            "PUSH.D     W10         \n"
            "PUSH.D     W12         \n"
            "PUSH       W14         \n"
            "PUSH       RCOUNT      \n"
            "PUSH       TBLPAG      \n"
            "PUSH       ACCAL       \n"
            "PUSH       ACCAH       \n"
            "PUSH       ACCAU       \n"
            "PUSH       ACCBL       \n"
            "PUSH       ACCBH       \n"
            "PUSH       ACCBU       \n"
            "PUSH       DCOUNT      \n"
            "PUSH       DOSTARTL    \n"
            "PUSH       DOSTARTH    \n"
            "PUSH       DOENDL      \n"
            "PUSH       DOENDH      \n"                                                                                 
            "PUSH       CORCON      \n"
            "PUSH       PSVPAG      \n"
            "MOV        W15, _stackPointer  \n");   

这解决了我遇到的所有问题