首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >手臂皮质m4 xPSR在分支时的变化

手臂皮质m4 xPSR在分支时的变化
EN

Stack Overflow用户
提问于 2017-05-11 21:31:27
回答 1查看 1.2K关注 0票数 1

我正在写一个操作系统...我正在研究上下文切换..我可以将内核切换到用户程序,然后再返回。但是SVC调用似乎不能很好地工作。

代码语言:javascript
复制
syscall:
    svc SYSCALL_SVC_NUMBER
    bx lr

当调用svc触发中断时,我可以看到控制流返回到内核。当它返回到用户程序时,硬故障出现了。

在这里--> bx lr

我已经检查了所有寄存器是否正确加载,除了xPSR缺少拇指位。这就是硬故障出现的原因。

但我不知道为什么xPSR是清楚的为零..。

代码语言:javascript
复制
.global activate
activate:
/* save kernel state in ip register */
mrs ip, psr
push {r4, r5, r6, r7, r8, r9, r10, r11, ip, lr}

/* switch to process stack */
msr psp, r0

mov ip, #2
msr control, ip

ldr ip, [sp, #0x38]
msr psr_nzcvq, ip

/* load user state */
pop {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, lr}
add sp, #0x8
ldr ip, [sp, #-0x8]
/* this line can branch correctly */
bx ip
EN

回答 1

Stack Overflow用户

发布于 2017-05-12 09:36:05

啊,是的,你是对的,但是你不需要同时修改任何东西。

以下面的代码为例

代码语言:javascript
复制
mov r1,#0x22
mov r2,#0x33
mov r3,#0x44
mov r0,#0x55
mov r12,r0
mov r0,#0x66
mov r14,r0
mov r0,#0x11
svc #1

当堆栈命中svc处理程序时,它看起来像这样。

可以肯定的是,这是有文档记录的

代码语言:javascript
复制
20000FD4 FFFFFFF9     return address                                                                        
20000FD8 00000011     r0                                                                        
20000FDC 00000022     r1                                                                        
20000FE0 00000033     r2                                                                        
20000FE4 00000044     r3                                                                        
20000FE8 00000055     r12                                                                        
20000FEC 00000066     r14                                                                        
20000FF0 0100009E     r15                                                                        
20000FF4 21000000     xPSR

在cortex-m上的例外情况下,它们在硬件中的行为方式可以根据它们的调用约定直接调用C函数。了解程序计数器本身的lsbit为0,1的lsbit用于BX,BLX和POP,它被这些指令用来确定ARM或THUMB模式,该位被剥离,然后用作PC。

从SVC返回的结果可以/应该类似于上面的内容。如果您想使用svc或任何其他中断来执行上下文切换,则需要构建与之匹配的堆栈。

当然,对于每个线程,都存在一些先有鸡还是先有蛋的问题,您可以构建一个类似上面的堆栈映像

代码语言:javascript
复制
20000FD4 FFFFFFF9                                                                             
20000FD8 00000011                                                                             
20000FDC 00000022                                                                             
20000FE0 00000033                                                                             
20000FE4 00000044                                                                             
20000FE8 00000055                                                                             
20000FEC 00000066                                                                             
20000FF0 01001234                                                                         
20000FF4 21000000 

但是你可以把“不关心”放在寄存器中,除了你设置为线程入口点的pc。未设置lsbit的情况下。此外,您还需要一些结构来保存其他寄存器的状态。

然后,当您进行上下文切换时,您将上述以外的寄存器保存在某个结构中,该结构包括sp,然后从下一个线程填充这些寄存器,包括它的sp。然后你bx lr返回。

除此之外,还有更多信息,请参阅atomthreads或chibios或其他开放源码的功能操作系统。

被中断的地址是正确的,或者在这种情况下,svc之后的地址,程序计数器,在没有设置lsbit的情况下位于堆栈上,但同时也是正确的。用于从异常(svc或计时器中断等)返回的实际lr是特殊的0xFFFxxxx,它设置了lsbit。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43916933

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档