armasm: Use of MRS and MSR instructions ('Deprecated form of PSR field specifier')

来源:互联网 发布:西安爱知中学怎么样 编辑:程序博客网 时间:2024/06/05 01:51

Applies to: Software Development Toolkit (SDT)

Description
The ARM instructions MRS and MSR are used to read and write the Current Program Status Register (CPSR) and Saved Program Status Registers (SPSRs) of the ARM core. These are commonly used to change processor mode and to enable/disable interrupts, when the core is in a privileged mode (i.e. not User mode).

These instructions are described in the ARM Architecture Reference Manual ('ARM ARM'), but unfortunately in early versions of the book the range of different instruction forms is not fully described. In addition, the descriptions of these instructions in the ARM6 & ARM7 family datasheets are incomplete.

MRS transfers the CPSR or the SPSR of the current mode to a general-purpose register.

MSR transfers the value of a general-purpose register or immediate constant to the CPSR or the SPSR of the current mode.

The status registers are split into four 8-bit fields that can be individually written:

Control (c) bits 0-7 5 processor mode bits, I & F interrupt disable bits, and the T bit on ARMv4T.
Extension (x) bits 8-15  Reserved for future use (unused in Arch 3, 4 & 4T)
Status  (s) bits 16-23 Reserved for future use (unused in Arch 3, 4 & 4T)
Flags  (f) bits 24-31 NZCV flags (28-31) and 4 bits (24-27) reserved for future use

Bits that are reserved for future use should not be modified by current software. Typically, a read-modify-write strategy should be used to update the value of a status register to ensure future compatibility. For an example, see armcc: Inline assembler __asm. Note that the T bit in the CPSR should never be changed directly by writing to the PSR (use the BX instruction to change state instead).

However, in cases where the processor state is known in advance (e.g. on reset, following an interrupt, or some other exception), an immediate value may be written directly into the status registers, to change only specific bits (e.g. to change mode). For an example, see Writing interrupt handlers.

Instruction Formats and Usage
The ARM assembler (armasm) supports the full range of MRS and MSR instructions, in the form:

 MRS(cond) Rd, CPSR
 MRS(cond) Rd, SPSR
 MSR(cond) CPSR_fields, Rm
 MSR(cond) SPSR_fields, Rm
 MSR(cond) CPSR_fields, #immediate
 MSR(cond) SPSR_fields, #immediate

where 'fields' can be any combination of "cxsf".

Note that MSR CPSR_c, #immediate is a legitimate instruction (despite what is written in early versions of the ARM ARM), so a sequence of two instructions like:

 MOV r0, #0x1F
 MSR CPSR_c, r0

as commonly found in boot code, can be combined into one instruction, like:

MSR CPSR_c, #0x1F ; go to System mode, IRQ & FIQ enabled

This immediate form of MSR can actually be used with any of the field masks, but care must be taken that a read-modify-write strategy is followed so that currently unallocated bits are not affected. Otherwise the code could have distinctly different effect on future cores where such bits are allocated. When used with the flag bits, the immediate form is shielded from this as bits 27-24 can be considered to be read only.

For MSR operations, we recommend that only the minimum number of fields are written, because some ARM implementations may need to take extra cycles to write specific fields; by not writing to fields which don't need changing reduces any such extra cycles to a minimum. For example, ARM9 needs more cycles than an ARM7 to execute an MSR when the CPSR control field is modified, to allow the changes to propagate through the pipeline correctly, so that register reads for the following instruction come from the correct banked registers.

For example, an MRS/BIC/ORR/MSR sequence to change processor mode is best written with the last instruction being MSR CPSR_c, Rm, though any other set of fields that includes 'c' will also work.

As another example, to restore a saved PSR value (where all fields need to be restored), you should use MSR SPSR_cxsf, Rm.

Be aware, however, that there is unfortunately a bug in the SDT 2.50 ARMulator - it fails to execute instructions with 'x' & 's' (you may see 'Undefined Instruction' instead) - see MSR SPSR_cxsf,Rm gives Undefined Instruction with ARMulator. This is fixed in SDT 2.51

To execute your code under the SDT 2.50 ARMulator, we suggest you apply the following workaround to your assembler sources:

IF :DEF: ARMULATOR_WORKAROUND
 MSR SPSR_cf, R0
ELSE
 MSR SPSR_cxsf, R0
ENDIF

Earlier releases of the assembler allowed other forms of the MSR instruction to modify the control field and flags field:

cpsr or cpsr_all  Control and flags field.
cpsr_flg  Flags field only.
cpsr_ctl  Control field only

and similarly for SPSR. These forms are now deprecated, so should not be used. If your legacy code contains them, the assembler will report:

Warning: Deprecated form of PSR field specifier used (use _cxsf)

In most cases, you should simply modify your code to use '_c', '_f', '_cf' or '_cxsf' instead.


原文地址:http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/1472.html

原创粉丝点击