-
操纵 32 位 PSR 的指令
你不能在 32 位模式中使用 MOVS PC, R14
或 LDMFD R13!, {registers, PC}^
。也不能使用 ORRS PC, R14, #1<<28
来设置 V 标志。现在需要使用 MRS
和 MSR
。
复制一个寄存器到 PSR 中 MSR CPSR, R0 ; 复制 R0 到 CPSR 中 MSR SPSR, R0 ; 复制 R0 到 SPSR 中 MSR CPSR_flg, R0 ; 复制 R0 的标志位到 CPSR 中 MSR CPSR_flg, #1<<28 ; 复制(立即值)标志位到 CPSR 中
复制 PSR 到一个寄存器中 MRS R0, CPSR ; 复制 CPSR 到 R0 中 MRS R0, SPSR ; 复制 SPSR 到 R0 中指令格式
你有两个 PSR - CPSR
是当前的程序状态寄存器(Current Program Status Register),而 SPSR
是保存的程序状态寄存器(Saved Program Status Register)(前面的处理器模式的 PSR)。每个有特权的模式都有自己的 SPSR,可获得的 PSR 有:
- CPSR_all - 当前的
- SPSR_svc - 保存的,SVC(32) 模式
- SPSR_irq - 保存的,IRQ(32) 模式
- SPSR_abt - 保存的,ABT(32) 模式
- SPSR_und - 保存的,UND(32) 模式
- SPSR_fiq - 保存的,FIQ(32) 模式
_flg
后缀允许你改变标志位而不影响控制位。
在 user(32) 模式中,保护 CPSR 的控制位,你只能改变条件标志。在其他模式中,可获得整个 CPSR。你不应该指定 R15 为一个源寄存器或一个目标寄存器。最后,在 user(32) 模式中,你不能尝试访问 SPSR,因为它不存在!
要设置 V 标志:
MSR CPSR_flg, #&10000000这将设置 V 标志但不影响控制位。
要改变模式:
MRS R0, CPSR_all ; 复制 PSR BIC R0, R0, #&1F ; 清除模式位 ORR R0, R0, #new_mode ; 把模式位设置为新模式 MSR CPSR_all, R0 ; 写回 PSR,变更模式
现在我们要做的是进入 SVC32 模式并设置 Z 标志。接着我们返回 SVC26 模式并‘测试’是否设置了 Z。
RISC OS 不希望发现自己处在 32 位模式中,所以我们要禁止所有中断并保持它们这样(keep them that way)。尽管这些代码应该执行的非常快,但我们不应当冒任何风险...
你可能觉得 32 位模式不是非常有用。在当前版本的 RISC OS 下,这是事实。实际上,就我而言,32 位模式提供给你的只是:
- 访问大于 28Mb 的区域。在 RISC OS 上这不是真的很重要,在这个系统里 web 浏览器适合于 1 M 或 2 M,而重要的艺术程序为那些非常巨大的图象提供它们自己的虚拟内存系统。
本文档的最初版本,和最初的 ARM 汇编器指南包括...
- StrongARM 提供了两个指令(UMUL 和 UMLA、IIRC),它们处理 64 位乘法。这只能在 32 位模式下获得。
尽管 32 位模式的利益好象不是多的那么惊人,新近的处理器(比如 Xscale)不再支持 26 位模式,所以 RISC OS 和它的应用程序要在 32 位环境下工作则必须经过修改。听起来不是很多,但是如果所有补偿/改变 R15 中的 PSR 位的引用都必须被变更为对不在 R15 中的独立的 PSR 的引用,这就突然变成一个非常重大的问题了。还有你不能继续用一个指令来恢复 PSR 并分支回到调用者,现在这需要两个独立的指令。为此代码必须重写。你不能简单的用另一个指令来修补...