Ora

What Are Branch Instructions in ARM Processor?

Published in ARM Processor Control Flow 6 mins read

Branch instructions in an ARM processor are fundamental commands that alter the normal sequential flow of program execution, allowing the processor to jump to a different part of the code. These instructions are essential for implementing control flow structures like loops, conditional statements (if/else), and function calls.

Branch instructions work by changing the value of the Program Counter (PC), which holds the address of the next instruction to be executed. When a branch instruction is encountered, the PC is updated to point to the target address, causing the processor to fetch and execute instructions from that new location.

Types of Branch Instructions

ARM processors support various types of branch instructions, primarily categorized into unconditional and conditional branches, with further specialized variants for subroutine calls and state switching.

1. Unconditional Branch

An unconditional branch instruction always causes the program flow to divert to a new address. There is no condition that needs to be met; the branch always occurs.

  • Instruction: The most common unconditional branch instruction is B.
  • Purpose: Used for direct jumps, creating infinite loops, or skipping over sections of code.
  • Example: If you want to jump directly to a label named Start_Again, you would use B Start_Again.

2. Conditional Branch

A conditional branch instruction only causes a branch if a specific condition is met. These conditions are typically determined by the state of the Condition Code Flags (N, Z, C, V) in the Current Program Status Register (CPSR), which are updated by previous arithmetic or logical operations.

  • Instructions: Conditional branches are denoted by B followed by a condition code, such as:
    • BEQ (Branch if Equal) - branches if the Zero flag (Z) is set.
    • BNE (Branch if Not Equal) - branches if the Zero flag (Z) is clear.
    • BGT (Branch if Greater Than) - branches if the result of a comparison indicates greater than (signed).
    • BLT (Branch if Less Than) - branches if the result of a comparison indicates less than (signed).
    • BHS (Branch if Higher or Same / Carry Set) - branches if the Carry flag (C) is set.
    • BLO (Branch if Lower / Carry Clear) - branches if the Carry flag (C) is clear.
  • Purpose: Essential for implementing if-else statements, for loops, and while loops, where execution flow depends on data values.
  • Example: After comparing two numbers, CMP R0, #10, you might use BEQ Exit_Loop to jump out of a loop if R0 equals 10.

3. Branch with Link (Subroutine Calls)

Branch with Link instructions are specifically designed for calling subroutines or functions. They perform a branch operation but also save the address of the instruction following the branch into the Link Register (LR, which is R14). This allows the program to return to the original execution path after the subroutine completes.

  • Instructions:
    • BL (Branch with Link): Jumps to a target address and stores the return address in LR.
    • BLX (Branch with Link and eXchange): Jumps to a target address, stores the return address in LR, and can switch the processor state between ARM and Thumb instruction sets.
  • Purpose: Facilitates modular programming by enabling function calls and returns.
  • Returning: A typical return from a subroutine involves moving the value from LR back into the Program Counter (MOV PC, LR).
  • Example: BL MyFunction will call MyFunction, and upon completion, MOV PC, LR within MyFunction will return control to the instruction after BL MyFunction.

4. Branch and Exchange (State Switching)

Branch and Exchange instructions are used to branch to a new address and potentially switch the instruction set state of the processor (between ARM and Thumb modes). This is particularly useful in mixed-mode code.

  • Instructions:
    • BX (Branch and eXchange): Branches to an address specified in a register and can switch instruction set state. The lowest bit of the target address register determines the new state (0 for ARM, 1 for Thumb).
    • BLX (as mentioned above): Combines linking with state exchange.
  • Purpose: Allows smooth transitions between ARM (32-bit instructions) and Thumb (16-bit instructions) code sections, optimizing code density and performance.

How Branching Works

When a branch instruction executes, the ARM processor updates its Program Counter (PC).

  • For simple branches (B, BL), the PC is loaded with the target address.
  • For conditional branches (BEQ, BNE, etc.), the processor first checks the relevant flags in the CPSR. If the condition is true, the PC is updated; otherwise, execution continues with the next instruction in sequence.
  • For BL and BLX, the address of the instruction immediately after the branch instruction is saved in the Link Register (LR) before the PC is updated.

Key ARM Branch Instructions Summary

The table below summarizes the primary branch instructions in ARM.

Instruction Type Description Usage
B Unconditional Always branches to the target address. Direct jumps, infinite loops
BEQ Conditional Branches if the Zero flag (Z) is set (result was equal). if (x == y)
BNE Conditional Branches if the Zero flag (Z) is clear (result was not equal). if (x != y)
BGT, BLT Conditional Branches if Greater Than / Less Than (signed comparison). if (x > y), if (x < y)
BHS, BLO Conditional Branches if Higher or Same (carry set) / Lower (carry clear) (unsigned). if (x >= y) (unsigned), if (x < y) (unsigned)
BL Link Branches to a subroutine, saving the return address in LR. Function/subroutine calls
BX Exchange Branches to an address in a register and can switch ARM/Thumb state. State switching, indirect jumps
BLX Link & Exchange Branches, saves return address in LR, and can switch ARM/Thumb state. Calling functions across ARM/Thumb modes

Practical Applications and Examples

  • Looping: Branch instructions are fundamental for creating loops.

    ; Example: Simple decrementing loop
    MOV R0, #10     ; Initialize counter R0 = 10
    Loop_Start:
        SUB R0, R0, #1  ; Decrement R0
        CMP R0, #0      ; Compare R0 with 0
        BNE Loop_Start  ; If R0 is not equal to 0, branch back to Loop_Start
    ; Loop ends here when R0 is 0
  • Conditional Execution: Implementing if-else logic.

    ; Example: If R0 equals 5, jump to Process_Five
    CMP R0, #5
    BEQ Process_Five
    ; Code for when R0 is not 5
    B End_If
    
    Process_Five:
        ; Code for when R0 is 5
    End_If:
        ; Continue program flow
  • Function Calls: Using BL to call a function and MOV PC, LR to return.

    ; Main program
    ...
    BL CalculateSum     ; Call the CalculateSum subroutine
    ...
    ; Program continues after subroutine returns
    
    CalculateSum:
        ; Subroutine code to calculate a sum
        ; ...
        MOV PC, LR      ; Return from subroutine

Branch instructions are critical for controlling the flow of execution in ARM assembly language, enabling complex program logic and efficient use of system resources.