The Application Program Status Register (APSR) in Arm Cortex-M is a 32-bit register that contains application-level status and control information. It provides details on the conditional execution status of an application program and allows modification of the condition flags. The APSR is made up of multiple fields that can be individually accessed to check or update specific status bits. Key fields include the Negative (N) flag, Zero (Z) flag, Carry (C) flag, Overflow (V) flag, and the Execution Program Status Register (EPSR). Understanding the layout and functionality of the APSR is critical for efficiently controlling conditional execution in Cortex-M applications.
Overview of APSR
The APSR is one of the system control registers implemented in all Cortex-M processors. It holds condition flags that indicate the results of arithmetic and logical instructions executed by the application program. These flags are tested by conditional execution instructions to determine whether a given instruction should execute or not. The APSR also contains the current execution state bits of the EPSR, which controls the instruction set state and stack pointer used by exception handlers.
Unlike the EPSR, the APSR cannot be directly read or written to. Instead, specific fields must be accessed using register aliases. For example, the APSR contains the N, Z, C, and V flags which can be read and updated via the APSR_nzcv alias. The EPSR execution state fields are available through APSR_exc. This architecture prevents corruption of the APSR and allows context switching by exception handlers without saving/restoring the entire register.
APSR Fields
The APSR contains the following key status fields:
- N – Negative condition flag
- Z – Zero condition flag
- C – Carry condition flag
- V – Overflow condition flag
- Q – Cumulative saturation bit
- EPSR – Execution Program Status Register
Negative (N) Flag
The N flag indicates the sign of the result of the last instruction. A value of 1 means the result was negative, while 0 means it was positive. Instructions that can affect the N flag include arithmetic, logical, and move operations. The N flag is used by conditional instructions for comparisons and to implement signed multiplication/division.
Zero (Z) Flag
The Z flag is set to 1 when the result of the last instruction is zero, and to 0 otherwise. Instructions that can set the Z flag include logical, arithmetic, and move operations. The Z flag supports conditional execution after compare instructions and for implementing conditional loops.
Carry (C) Flag
The C flag contains the carry condition from arithmetic operations. It is set to 1 if an instruction results in a carry or borrow condition. For example, an ADC (add with carry) instruction will set the C flag to 1 if there is a carry out of the most significant bit. The C flag can be tested by conditional instructions and enables arithmetic operations to propagate carries across multiple words.
Overflow (V) Flag
The V flag is used to indicate signed overflow after arithmetic operations. It is set to 1 if the operation on two signed values produces a result that cannot be represented in the destination register size. For example, adding two large positive numbers may produce a negative result which cannot be signed. The V flag supports efficient overflow handling in signed arithmetic.
Cumulative Saturation (Q) Bit
The Q bit is set to 1 whenever signed or unsigned saturation occurs in an instruction. Saturation clamps results to the largest positive or smallest negative value if outside the range. The Q bit accumulates any saturation events, allowing conditional code to detect and handle saturation conditions.
Execution Program Status Register (EPSR)
The EPSR field holds execution state bits and stack pointer selection values for exception handlers. This includes the Instruction Set State (ISS) bit, Exception Number (EXC_NUM) field, and Execution Mode (EXEC_MODE) bits. These status bits control the stack pointer, execution mode, and instruction set used when exception handlers are activated.
Accessing APSR Fields
As mentioned earlier, the APSR cannot be directly accessed as a whole. Instead, the following register aliases are used to read and modify specific APSR fields:
- APSR_nzcv – Allows access to the N, Z, C, and V flags.
- APSR_g – Provides access to the Q flag.
- APSR_exc – Used to read/write the EPSR state bits.
For example, to update the N and Z flags based on some condition:
; Set N and Z flags
MOV R1, #1
CMP R0, R1
IT NE
MOVNE APSR_nzcv, #0b0100 ; N=1, Z=0 if R0 != R1
And to check for cumulative saturation:
; Test if saturation occurred
CMP APSR_g, #1
BEQ saturation_detected
Using APSR Flags for Conditional Execution
A key use case of the APSR flags is to enable conditional execution of instructions. Based on the results of a previous instruction, a conditional instruction can decide whether to execute or not using the following steps:
- Execute an instruction that sets appropriate N, Z, C, V flags
- Perform a conditional check on flags using a ‘TST’, ‘CMP’ or ‘TEQ’ instruction
- Execute a conditional instruction based on flags state
For example:
; Step 1 - Perform substraction
SUBS R0, R1, #5
; Step 2 - Test if result is non-negative
CMP APSR_nzcv, #0b0000
; Step 3 - Conditionally execute ADD
IT GE
ADDGE R2, R3, R0
In this case, the conditional ADD instruction will only execute if R0 is greater than or equal to zero after the substraction. The SUBS sets the N and Z flags, CMP checks them against the ‘GE’ condition, and ADDGE performs the addition only if the condition passes.
Saving/Restoring APSR
During context switching, such as when an exception occurs, the APSR contents must be preserved. This is done by pushing the APSR_nzcv and APSR_exc aliases onto the stack frame:
; Save APSR flags for current context
PUSH {APSR_nzcv, APSR_exc}
; ... exception handler code ...
; Restore APSR flags before returning
POP {APSR_nzcv, APSR_exc}
This allows the exception handler to use the APSR without corrupting the application program’s flags. Other register aliases like CONTROL and APSR_g do not need to be saved/restored.
Summary
In summary, the key points about the Application Program Status Register in Cortex-M are:
- APSR holds status flags like N, Z, C, V used for conditional execution
- Also contains EPSR register with execution state bits
- Specific fields are accessed via aliases like APSR_nzcv
- Flags are checked by conditional instructions to control execution
- Must be partially saved/restored during context switching
Properly utilizing the APSR is critical for efficient conditional code and handling exceptions in Cortex-M applications. Understanding how to manipulate the flags, test conditions, and preserve context enables optimized embedded software.