根据ARM手册,应该可以访问特定CPU模式的分组寄存器,例如“r13_svc”。当我尝试这样做时,gcc对我大吼大叫,出现以下错误:
立即表达式需要#前缀 - “mov r2,sp_svc”
怎么了?
更新。 ARMv5和ARMv6的ARM体系结构参考手册中的以下文本使我相信它是可能的,第A2.4.2节:
寄存器R13和R14有6个存储区 每个物理寄存器。一个被使用 在用户和系统模式,以及每个模式 其余五个用于其中一个 五种例外模式。在哪儿 有必要具体说明哪一个 正在引用的版本,您使用 形式的名称:R13_mode 模式为的R14_mode 适当的usr,svc(for 主管模式),abt,und,irq和 FIQ。
答案 0 :(得分:6)
正确的语法是mrs r2,sp_svc
或mrs r3, sp_usr
。这是一个新的 armv7 扩展程序。可以在ARM Linux KVM源文件interrupt_head.S中看到该代码。 Matthew Gretton-Dann撰写的{{3>} gas binutils补丁。它需要虚拟化扩展,据我所知。
根据我的理解,LPAE(大型物理地址扩展)意味着虚拟化扩展。因此,Cortex-A7,Cortex-A12,Cortex-A15和Cortex-A17可能能够使用此扩展。但是,Cortex-A5,Cortex-A8和Cortex-A9不能。
有关该指令的文档可在 ARMv7a TRM revC中的 B9.3.9 MRS(Banked register)部分下找到。
对于其他Cortex-A(和ARMv6)CPU,您可以使用cps
指令切换模式并将存储寄存器传输到非存储寄存器(R0-R7),然后切换回。显而易见的困难在于用户模式。处理此问题的正确方法是使用ldm rN, {sp,lr}^
;用户模式没有简单的方法回到特权模式。
对于所有旧CPU,Dwelch提供的信息都可以使用。主要是,使用mrs/msr
来更改模式。
这是上下文切换的重要指令(虚拟机做了很多)。
答案 1 :(得分:3)
我认为mov
指令不可能;至少根据我正在阅读的ARM体系结构参考手册。你有什么文件?有ldm
的变体可以从特权模式加载用户模式寄存器(使用^
)。您唯一的选择是切换到SVC模式,执行mov r2, sp
,然后切换回您正在使用的任何其他模式。
您收到的错误是因为它无法理解sp_svc
,因此它认为您正在尝试立即mov
,这看起来像是:
mov r2, #0x14
这就是为什么它说“需要#前缀”。
答案 2 :(得分:2)
使用mrs和msr通过更改cpsr中的位来更改模式,然后正常使用r13。
从手臂
MRS R0,CPSR BIC R0,R0,#0x1F ORR R0,R0,#0x13 MSR CPSR_c,R0
然后
mov sp,#0x10000000
或者如果你需要更多的位
ldr sp,=0x12345600
或者如果您不希望汇编程序放置您的数据,您可以自己放置它。
ldr sp,svc_stack b 1f svc_stack: .word 0x12345600 1:
您将看到典型的arm启动代码,其中应用程序将支持中断,中止和其他异常,设置您将需要的所有堆栈指针,更改模式,设置sp,更改模式,设置sp ,改变模式......