SoC
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
  • Arm Cortex M3
  • Contact
Reading: Conditional vs Unconditional Branches and Processor Mode in Arm
SUBSCRIBE
SoCSoC
Font ResizerAa
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Search
  • Home
  • Arm
  • Arm Cortex M0/M0+
  • Arm Cortex M4
Have an existing account? Sign In
Follow US
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
© S-O-C.ORG, All Rights Reserved.
Arm

Conditional vs Unconditional Branches and Processor Mode in Arm

Javier Massey
Last updated: September 28, 2023 2:07 pm
Javier Massey 9 Min Read
Share
SHARE

The ARM architecture supports both conditional and unconditional branches to alter the flow of program execution. Conditional branches test a condition code and branch if the condition is true, while unconditional branches always branch. The processor mode determines which instructions are available and what privileges the code has access to. This article will explore conditional versus unconditional branches, explain the available processor modes, and discuss how branches and modes interact on ARM processors.

Contents
Conditional BranchesCondition CodesRange of Branch OffsetsUnconditional BranchesRange of Unconditional Branch OffsetsInteractions Between Branches and Processor ModesARM Processor ModesBranching Between ModesMode-Specific Branch InstructionsTypical Uses of BranchesExample: Branching in a Function CallConclusion

Conditional Branches

Conditional branches allow branching based on the result of a comparison or test. ARM supports a set of condition codes that represent possible results of a comparison, like equals, greater than, less than, etc. Conditional branch instructions check the condition code and branch if the condition is true.

For example, the branch if equal instruction (BEQ) checks if the zero bit is set in the condition flags register. If the last comparison was an equality check that set the flags, BEQ branches. Otherwise, it falls through. Other conditional branch instructions check other condition codes. This allows efficient conditional program flow without explicitly testing a condition in code.

Here is an example pseudo-code using BEQ: CMP R0, R1 // Compare R0 and R1 BEQ label // Branch if equal … label: // Do something

Conditional branches are powerful because they avoid the need to explicitly evaluate conditions with additional instructions. The processor handles the test automatically.

Condition Codes

The condition codes checked by conditional branch instructions indicate the result of the last comparison, which sets the flag bits in the Application Program Status Register (APSR). There are several condition codes that can be tested:

  • Equal (Z set) – BEQ
  • Not equal (Z clear) – BNE
  • Unsigned higher or same (C set) – BHS
  • Unsigned lower (C clear) – BLO
  • Signed greater than or equal (N==V) – BGE
  • Signed less than (N!=V) – BLT
  • Signed greater than (Z==0, N==V) – BGT
  • Signed less than or equal (N!=V) – BLE

The conditional branch checks the flags set by the previous instruction that set the condition codes. This avoids explicit comparison logic before the branch.

Range of Branch Offsets

The branch instructions specify a label to branch to. This label is encoded as a relative offset from the branch instruction’s own address. Different conditional branch instructions support different sized offsets:

  • BEQ, BNE – +/- 16MB offset
  • BGE, BLT – +/- 1MB offset
  • BGT, BLE – +/- 32KB offset

This relative offset range determines how far away the label target can be placed. For long distance branches, it may be necessary to use multiple branches.

Unconditional Branches

Unconditional branches always branch to the target location, regardless of flags or condition codes. These include direct branches (B) and indirect branches (BLX).

The B instruction branches to a label at a relative offset. BLX branches to an address in a register. Both happen unconditionally.

For example: B label // Always branches to label BLX R3 // Branches to address in R3

Unconditional branches are used when you want to redirect execution flow without testing a condition. They are simpler than conditional branches but less flexible.

Range of Unconditional Branch Offsets

The ARM B instruction supports a relative offset of +/- 32MB, allowing branches over a large region of code. BLX uses an address stored in a register, so the destination can be anywhere within the 32-bit address space.

Interactions Between Branches and Processor Modes

ARM processors support different processor modes with varying levels of privilege. The mode determines what instructions can execute and what system resources are accessible. The branches available and their behavior depends on the current mode.

ARM Processor Modes

The key ARM processor modes are:

  • User – Low privilege, cannot access system resources
  • FIQ – Supports fast interrupts, has some privilege
  • IRQ – Used for general interrupts, has some privilege
  • Supervisor – Protected mode for OS kernels, high privilege
  • Abort mode – Entered on data or instruction aborts
  • Undefined mode – Entered on attempt to execute undefined instructions
  • System mode – Highest privilege, can execute any instruction

The current mode is defined in the Current Program Status Register (CPSR). Code can switch between modes using special instructions like MOV, MSR, OR MRS when privilege allows.

Branching Between Modes

Branches can target code in the same or different mode. However, branching from a low privilege mode to code in a higher privilege mode is prohibited. Attempting an illegal branch raises an exception.

For example, code running in User mode cannot branch directly to Supervisor mode code. But Supervisor mode code can branch freely. Restricting branches prevents User mode from accessing protected system resources.

Mode-Specific Branch Instructions

Some branch instructions are only available in specific modes due to privilege restrictions. For example:

  • RFE – Return from exception, only in exception modes
  • ERET – Return from exception ERET, only in exception modes
  • SRS – Store return state, only in non-User modes
  • BXJ – Branch exchange with link to Java state, only in Jazelle state

Attempting to execute these branches in the wrong mode will trigger an Undefined Instruction exception.

Typical Uses of Branches

Branches are used extensively in ARM code to implement conditional flows and redirects. Some typical examples include:

  • Multi-way conditional code – Use a series of conditional branches to check multiple conditions.
  • Complex conditionals – Combine multiple conditional branches to test compound conditions.
  • Looping constructs – Branches can implement loops of various types.
  • Subroutine returns – Return to the calling code after a procedure.
  • Interrupt handling – Branch to interrupt handlers based on interrupt triggers.
  • State machines – Branches allow compact state machine implementations.
  • Error handling – Branch to error handling code when exceptions occur.

Both conditional and unconditional branches are used extensively for these purposes. Using the appropriate branches and managing the mode transitions properly is key to efficient ARM programming.

Example: Branching in a Function Call

Here is an example of how branches are used to implement a simple C function call in ARM assembly: // Function declaration int myFunction(int arg1, int arg2); // Calling code MOV R0, #1 // Set first argument MOV R1, #2 // Set second argument BL myFunction // Call function // Function definition myFunction: PUSH {R4, LR} // Save registers … // Do function work MOV R0, #10 // Return value in R0 POP {R4, LR} // Restore registers BX LR // Return to caller

This shows both an unconditional BL branch to perform the call, and a conditional BX return branch. The LR register is used to hold the return address. Pushing and popping LR around the function body preserves the right return location.

The branches allow easy redirection of code flow to implement the call and return. The conditional BX makes sure to return properly after the function work completes.

Conclusion

In summary, ARM supports conditional and unconditional branches to alter program flow. Conditional branches test condition codes set by previous instructions while unconditional branches always redirect execution. The processor mode determines what branches are available and what modes code can branch between. Using the appropriate branches allows implementing conditional logic, loops, function calls, interrupts and more. Proper use of branches and managing mode changes are key skills for ARM developers.

Newsletter Form (#3)

More ARM insights right in your inbox

 


Share This Article
Facebook Twitter Email Copy Link Print
Previous Article Using BX and BLX Instructions Correctly in Thumb Code
Next Article Managing Reset Domains in Cortex-M3 Systems
Leave a comment Leave a comment

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

2k Followers Like
3k Followers Follow
10.1k Followers Pin
- Sponsored-
Ad image

You Might Also Like

RP2040 vs ESP32: How Do These Popular Microcontrollers Compare?

The Raspberry Pi RP2040 and Espressif ESP32 are two of…

9 Min Read

Debugging osDelay() Errors and Incorrect Behavior

The osDelay() function is used in embedded systems programming on…

7 Min Read

What are the key characteristics of ARM Cortex M0?

The ARM Cortex-M0 is a 32-bit processor designed for low-power…

10 Min Read

What instruction set does the Arm Cortex M0 support?

The Arm Cortex-M0 is a 32-bit RISC processor core that…

7 Min Read
SoCSoC
  • Looking for Something?
  • Privacy Policy
  • About Us
  • Sitemap
  • Contact Us
Welcome Back!

Sign in to your account