Assembly SVC呼叫后弹出错误的返回地址

Assembly SVC呼叫后弹出错误的返回地址,assembly,arm,stack,abort,cortex-a,Assembly,Arm,Stack,Abort,Cortex A,我正在开发一个定制处理器的ARM Cortex-A5内核,遇到了一个非常奇怪的问题,从软件的角度来看,这似乎是无法解释的。 问题在于,在对系统进行压力测试时(重新启动数百次),有时从某个SVC调用返回时会发生预回迁中止。调用的实现如下所示: 用户模式代码: ;...Stuff BL foo ;.. Stuff. foo PUSH {r4,lr} SVC #0x1a POP {r4,pc} SVC处理程序: SVC_Ha

我正在开发一个定制处理器的ARM Cortex-A5内核,遇到了一个非常奇怪的问题,从软件的角度来看,这似乎是无法解释的。 问题在于,在对系统进行压力测试时(重新启动数百次),有时从某个SVC调用返回时会发生预回迁中止。调用的实现如下所示:

用户模式代码:

;...Stuff
    BL       foo
;.. Stuff.

foo
    PUSH     {r4,lr}
    SVC      #0x1a 
    POP      {r4,pc}
SVC处理程序:

SVC_Handler
    PUSH     {r0-r12,lr}
    ;... Do stuff
    POP      {r0-r12,lr}
    SUBS     pc,lr,#0
当中止发生时,
LR\u USR
指向
BL foo
旁边的指令,但
IFAR
的值为零,且
r4
的值为零。因此is
LR_ABT
的值为
0x4
,如果我们尝试分支到地址0,这是有意义的。根据这些观察结果,
POP{r4,pc}
指令似乎正在从堆栈中提取两个零,而不是正确的值,这些值位于堆栈中的正确位置,正如在命中中止后用调试器观察到的那样(它们是
SP_USR
上方的两个字)。因此,看起来要么在pop指令发生后使用正确的值更新堆栈,要么就是
pop
指令出了问题

值得注意的是,代码和堆栈位于可缓存内存中。用户模式和SVC模式有不同的堆栈


这种影响可以从软件的角度解释,还是可能是硬件缺陷(内存/缓存控制器?)。有人在他们的职业生涯中见过类似的事情吗?不幸的是,只能事后调试。检测代码会将错误转移到另一个调用(是的,它是Heisenbug…)

为什么要这样修改pc?那么bx lr呢?根据Arm文档,这是从函数返回的完全合法的方式。更重要的是,
armcc
编译器是如何生成它的:)你确信问题在于代码或arm内核,而不是你正在测试的芯片?预取中止来自处理器总线,由not ARM逻辑生成。此时在该逻辑中发生了什么?
SVC\u处理器
以某种方式更改了
spsr
,可能无法返回到正确的模式。你检查了
cpsr
那里有
LR\u ABT
,应该是
spsr\u ABT
?@old\u timer此时我非常确信问题不在于代码,但把它贴在这里是为了让人更加确信:)但是,是的,不幸的是,系统非常复杂,但从理论上讲,这个特定的部分对于ARM核心应该是透明的。鉴于返回地址不正确,预回迁中止似乎非常合乎逻辑。问题是为什么它不好。