# Chapter 3: Basic ARM64 Instructions

## 3.1 What are Instructions?

Instructions are the basic commands that tell the computer what to do. Each instruction is a simple operation the processor can execute.

An instruction typically has two parts:

1. The operation (what to do)
2. The operands (what to do it with)

Example:

```
MOV x0, #42
```

* MOV: operation (move data)
* x0: destination operand
* \#42: source operand

**Main Categories of ARM64 Instructions**

ARM64 has several categories of instructions. We'll cover the following:

1. Data Processing Instructions
   * Perform operations on data in registers
   * Examples: ADD, SUB, AND, ORR
2. Memory Instructions
   * Move data between registers and memory
   * Examples: LDR (load), STR (store)
3. Branch Instructions
   * Control program flow
   * Examples: B (branch), BL (branch with link)
4. System Instructions
   * Interact with system features
   * Examples: SVC (supervisor call)

In the following sections, we'll explore each of these categories in detail, starting with Data Processing Instructions. We'll explain what each category does, provide examples, and show how they're used in real ARM64 assembly programming.\


## 3.2 Data Processing Instructions

Data Processing Instructions are fundamental operations in ARM64 assembly. They manipulate data within registers, forming the core of most computational tasks.

### 3.2.1 Integer Arithmetic

Arithmetic instructions perform basic mathematical operations on register values.

**ADD (Addition)**

```assembly
ADD Xd, Xn, Xm
```

This instruction adds the values in registers Xn and Xm, storing the result in Xd.

**Example:**

```assembly
ADD X0, X1, X2  ; X0 = X1 + X2
```

**Explanation:** If X1 contains 5 and X2 contains 3, after this instruction, X0 will contain 8.

**Answer:**

* Before: X1 = 5, X2 = 3
* After: X0 = 8 (5 + 3)

The ADD instruction is used for simple addition. It's commonly used in loops, array indexing, and general arithmetic calculations.

**SUB (Subtraction)**

```assembly
SUB Xd, Xn, Xm
```

This instruction subtracts the value in Xm from Xn, storing the result in Xd.

**Example:**

```assembly
SUB X0, X1, X2  ; X0 = X1 - X2
```

**Explanation:** If X1 contains 10 and X2 contains 7, after this instruction, X0 will contain 3.

**Answer:**

* Before: X1 = 10, X2 = 7
* After: X0 = 3 (10 - 7)

SUB is used for subtraction operations. It's often used in comparison operations, decrementing counters, and calculating differences.

**MUL (Multiplication)**

```assembly
MUL Xd, Xn, Xm
```

This instruction multiplies the values in Xn and Xm, storing the result in Xd.

**Example:**

```assembly
MUL X0, X1, X2  ; X0 = X1 * X2
```

**Explanation:** If X1 contains 6 and X2 contains 4, after this instruction, X0 will contain 24.

**Answer:**

* Before: X1 = 6, X2 = 4
* After: X0 = 24 (6 \* 4)

MUL is used for multiplication. It's common in mathematical computations, scaling values, and implementing algorithms that require multiplication.

**SDIV (Signed Division)**

```assembly
SDIV Xd, Xn, Xm
```

This instruction divides Xn by Xm (treating them as signed integers), storing the quotient in Xd.

**Example:**

```assembly
SDIV X0, X1, X2 ; X0 = X1 / X2
```

**Explanation:** If X1 contains 15 and X2 contains 3, after this instruction, X0 will contain 5.

**Answer:**

* Before: X1 = 15, X2 = 3
* After: X0 = 5 (15 / 3)

SDIV is used for integer division. It's important to note that this instruction handles signed division, meaning it works correctly with both positive and negative numbers.

Sure, let's add more detailed explanations of the basic concepts for each logical instruction along with the examples.

Let's break down the instructions with simpler and more detailed explanations using small numbers and binary representation to make it clearer.

### 3.2.2 Logical Instructions

#### AND Instruction

The **AND** instruction performs a bitwise AND between two registers. Each bit of the result is 1 if the corresponding bits of both operands are 1; otherwise, it is 0.

**Syntax**

```
AND <Rd>, <Rn>, <Rm>
```

* **Rd**: Destination register.
* **Rn**: First operand register.
* **Rm**: Second operand register.

**Example**

```assembly
AND X1, X2, X3
```

This instruction will perform a bitwise AND operation between the values in registers X2 and X3 and store the result in X1.

**Explanation**

Let's assume:

* X2 = 0x2 (in binary: 0010, in decimal: 2)
* X3 = 0x3 (in binary: 0011, in decimal: 3)

Bitwise AND operation:

```
X2: 0010 (2 in decimal)
X3: 0011 (3 in decimal)
-------------
X1: 0010 (2 in decimal)
```

Result stored in X1: 0x2 (2 in decimal)

#### ORR Instruction

The **ORR** instruction performs a bitwise OR between two registers. Each bit of the result is 1 if the corresponding bit of either operand is 1.

**Syntax**

```
ORR <Rd>, <Rn>, <Rm>
```

* **Rd**: Destination register.
* **Rn**: First operand register.
* **Rm**: Second operand register.

**Example**

```assembly
ORR X1, X2, X3
```

This instruction will perform a bitwise OR operation between the values in registers X2 and X3 and store the result in X1.

**Explanation**

Let's assume:

* X2 = 0x2 (in binary: 0010, in decimal: 2)
* X3 = 0x3 (in binary: 0011, in decimal: 3)

Bitwise OR operation:

```
X2: 0010 (2 in decimal)
X3: 0011 (3 in decimal)
-------------
X1: 0011 (3 in decimal)
```

Result stored in X1: 0x3 (3 in decimal)

#### EOR Instruction

The **EOR** instruction performs a bitwise Exclusive OR (XOR) between two registers. Each bit of the result is 1 if the corresponding bits of the operands are different; otherwise, it is 0.

**Syntax**

```
EOR <Rd>, <Rn>, <Rm>
```

* **Rd**: Destination register.
* **Rn**: First operand register.
* **Rm**: Second operand register.

**Example**

```assembly
EOR X1, X2, X3
```

This instruction will perform a bitwise XOR operation between the values in registers X2 and X3 and store the result in X1.

**Explanation**

Let's assume:

* X2 = 0x2 (in binary: 0010, in decimal: 2)
* X3 = 0x3 (in binary: 0011, in decimal: 3)

Bitwise XOR operation:

```
X2: 0010 (2 in decimal)
X3: 0011 (3 in decimal)
-------------
X1: 0001 (1 in decimal)
```

Result stored in X1: 0x1 (1 in decimal)

#### BIC Instruction

The **BIC** instruction performs a bitwise AND NOT operation between two registers. It clears the bits of the first operand that are set in the second operand.

**Syntax**

```
BIC <Rd>, <Rn>, <Rm>
```

* **Rd**: Destination register.
* **Rn**: First operand register.
* **Rm**: Second operand register.

**Example**

```assembly
BIC X1, X2, X3
```

This instruction will clear the bits in X2 that are set in X3 and store the result in X1.

**Explanation**

Let's assume:

* X2 = 0x3 (in binary: 0011, in decimal: 3)
* X3 = 0x2 (in binary: 0010, in decimal: 2)

Bitwise AND NOT operation:

```
X2: 0011 (3 in decimal)
X3: 0010 (2 in decimal)
-------------
X1: 0001 (1 in decimal)
```

Result stored in X1: 0x1 (1 in decimal)

#### ORN Instruction

The **ORN** instruction performs a bitwise OR NOT operation between two registers.

**Syntax**

```
ORN <Rd>, <Rn>, <Rm>
```

* **Rd**: Destination register.
* **Rn**: First operand register.
* **Rm**: Second operand register.

**Example**

```assembly
ORN X1, X2, X3
```

This instruction will perform a bitwise OR operation between X2 and the bitwise NOT of X3 and store the result in X1.

**Explanation**

Let's assume:

* X2 = 0x1 (in binary: 0001, in decimal: 1)
* X3 = 0x2 (in binary: 0010, in decimal: 2)

Bitwise OR NOT operation:

```
X2: 0001 (1 in decimal)
~X3: 1101 (bitwise NOT of X3, or in decimal: 13)
-------------
X1: 1101 (13 in decimal)
```

Result stored in X1: 0xD (13 in decimal)

#### EON Instruction

The **EON** instruction performs a bitwise Exclusive OR NOT operation between two registers.

**Syntax**

```
EON <Rd>, <Rn>, <Rm>
```

* **Rd**: Destination register.
* **Rn**: First operand register.
* **Rm**: Second operand register.

**Example**

```assembly
EON X1, X2, X3
```

This instruction will perform a bitwise XOR operation between X2 and the bitwise NOT of X3 and store the result in X1.

**Explanation**

Let's assume:

* X2 = 0x1 (in binary: 0001, in decimal: 1)
* X3 = 0x2 (in binary: 0010, in decimal: 2)

Bitwise XOR NOT operation:

```
X2: 0001 (1 in decimal)
~X3: 1101 (bitwise NOT of X3, or in decimal: 13)
-------------
X1: 1100 (12 in decimal)
```

Result stored in X1: 0xC (12 in decimal)\


### 3.2.3 **Comparison Instructions**

Comparison instructions are used to compare the values of two registers. The result of the comparison affects the condition flags (N, Z, C, V), which can be used in subsequent conditional instructions. The main comparison instructions in ARM64 are:

1. **CMP** - Compare
2. **CMN** - Compare Negative

#### CMP Instruction

The **CMP** (Compare) instruction compares the values of two registers by subtracting the second operand from the first operand. It sets the condition flags based on the result, but does not store the result.

**Syntax**

```
CMP <Rn>, <Rm>
```

* **Rn**: First operand register.
* **Rm**: Second operand register.

**Example**

```assembly
CMP X2, X3
```

This instruction will compare the values in registers X2 and X3 by performing the operation X2 - X3.

**Explanation**

Let's assume:

* X2 = 0x5 (5 in decimal)
* X3 = 0x3 (3 in decimal)

The comparison will perform:

```
X2 - X3
```

This is:

```
5 - 3 = 2
```

The condition flags are set as follows:

* **N (Negative)**: 0 (result is not negative)
* **Z (Zero)**: 0 (result is not zero)
* **C (Carry)**: 1 (no borrow, means X2 >= X3)
* **V (Overflow)**: 0 (no overflow)

#### CMN Instruction

The **CMN** (Compare Negative) instruction compares the values of two registers by adding the second operand to the first operand. It sets the condition flags based on the result, but does not store the result.

**Syntax**

```
CMN <Rn>, <Rm>
```

* **Rn**: First operand register.
* **Rm**: Second operand register.

**Example**

```assembly
CMN X2, X3
```

This instruction will compare the values in registers X2 and X3 by performing the operation X2 + X3.

**Explanation**

Let's assume:

* X2 = 0x2 (2 in decimal)
* X3 = 0x3 (3 in decimal)

The comparison will perform:

```
X2 + X3
```

This is:

```
2 + 3 = 5
```

The condition flags are set as follows:

* **N (Negative)**: 0 (result is not negative)
* **Z (Zero)**: 0 (result is not zero)
* **C (Carry)**: 0 (irrelevant in addition)
* **V (Overflow)**: 0 (no overflow)

### 3.2.4 Shift Instructions

Shift instructions are used to shift the bits in a register to the left or right. The main shift instructions in ARM64 are:

1. **LSL** - Logical Shift Left
2. **LSR** - Logical Shift Right
3. **ASR** - Arithmetic Shift Right

#### LSL Instruction

The **LSL** (Logical Shift Left) instruction shifts the bits of a register to the left by a specified number of positions. Zeros are shifted into the least significant bits.

**Syntax**

```
LSL <Rd>, <Rn>, #<shift>
```

* **Rd**: Destination register.
* **Rn**: Source register.
* **shift**: Number of positions to shift.

**Example**

```assembly
LSL X1, X2, #2
```

This instruction will shift the bits in register X2 to the left by 2 positions and store the result in X1.

**Explanation**

Let's assume:

* X2 = 0x2 (0010 in binary, 2 in decimal)

Logical Shift Left by 2 positions:

```
X2: 0010 (2 in decimal)
Shift:     00
-------------
X1: 1000 (8 in decimal)
```

Result stored in X1: 0x8 (8 in decimal)

#### LSR Instruction

The **LSR** (Logical Shift Right) instruction shifts the bits of a register to the right by a specified number of positions. Zeros are shifted into the most significant bits.

**Syntax**

```
LSR <Rd>, <Rn>, #<shift>
```

* **Rd**: Destination register.
* **Rn**: Source register.
* **shift**: Number of positions to shift.

**Example**

```assembly
LSR X1, X2, #2
```

This instruction will shift the bits in register X2 to the right by 2 positions and store the result in X1.

**Explanation**

Let's assume:

* X2 = 0x8 (1000 in binary, 8 in decimal)

Logical Shift Right by 2 positions:

```
X2: 1000 (8 in decimal)
Shift: 00
-------------
X1: 0010 (2 in decimal)
```

Result stored in X1: 0x2 (2 in decimal)

#### ASR Instruction

The **ASR** (Arithmetic Shift Right) instruction shifts the bits of a register to the right by a specified number of positions. The most significant bit (sign bit) is replicated into the shifted positions.

**Syntax**

```
ASR <Rd>, <Rn>, #<shift>
```

* **Rd**: Destination register.
* **Rn**: Source register.
* **shift**: Number of positions to shift.

**Example**

```assembly
ASR X1, X2, #2
```

This instruction will shift the bits in register X2 to the right by 2 positions and store the result in X1.

**Explanation**

Let's assume:

* X2 = 0xF8 (1111 1000 in binary, -8 in decimal using two's complement for negative numbers)

Arithmetic Shift Right by 2 positions:

```
X2: 1111 1000 (-8 in decimal)
Shift: 11
-------------
X1: 1111 1110 (-2 in decimal)
```

Result stored in X1: 0xFE (-2 in decimal)

### 3.2.5 Rotate Instructions

Rotate instructions are used to rotate the bits in a register around the end of the register. The main rotate instructions in ARM64 are:

1. **ROR** - Rotate Right
2. **ROL** - Rotate Left (not directly available in ARM64, can be achieved using ROR and appropriate shifts)

#### ROR Instruction

The **ROR** (Rotate Right) instruction rotates the bits of a register to the right by a specified number of positions. Bits shifted out of the least significant bit position are rotated back into the most significant bit position.

**Syntax**

```
ROR <Rd>, <Rn>, #<shift>
```

* **Rd**: Destination register.
* **Rn**: Source register.
* **shift**: Number of positions to rotate.

**Example**

```assembly
ROR X1, X2, #2
```

This instruction will rotate the bits in register X2 to the right by 2 positions and store the result in X1.

**Explanation**

Let's assume:

* X2 = 0xB (1011 in binary, 11 in decimal)

Rotate Right by 2 positions:

```
X2: 1011 (11 in decimal)
Rotate: 11
-------------
X1: 1110 (14 in decimal)
```

Result stored in X1: 0xE (14 in decimal)

#### ROL Instruction

The **ROL** (Rotate Left) instruction is not directly available in ARM64, but it can be achieved using the ROR instruction and appropriate shifts. Rotate Left by N positions is equivalent to Rotate Right by (32-N) positions.

**Example**

```assembly
LSL X1, X2, #2
LSR X3, X2, #30
ORR X1, X1, X3
```

This sequence of instructions will rotate the bits in register X2 to the left by 2 positions and store the result in X1.

**Explanation**

Let's assume:

* X2 = 0xB (1011 in binary, 11 in decimal)

Rotate Left by 2 positions:

1. Logical Shift Left by 2 positions:

```
X2: 1011 (11 in decimal)
Shift: 00
-------------
X1: 101100 (44 in decimal)
```

2. Logical Shift Right by 30 positions (equivalent to Rotate Right by 2 positions):

```
X2: 1011 (11 in decimal)
Shift: 11
-------------
X3: 10 (2 in decimal)
```

3. Bitwise OR of X1 and X3:

```
X1: 101100 (44 in decimal)
X3: 10 (2 in decimal)
-------------
X1: 101110 (46 in decimal)
```

Result stored in X1: 0x2E (46 in decimal)

#### &#x20;1. Practicle Example: data\_processing\_instructions.s

```assembly
.global _start
.section .text

_start:
    // Initialize registers
    mov x0, #10         // Set x0 to 10 (binary: 1010)
    mov x1, #3          // Set x1 to 3  (binary: 0011)

    // Arithmetic operations
    add x2, x0, x1      // Addition: x2 = x0 + x1
    sub x3, x0, x1      // Subtraction: x3 = x0 - x1
    mul x4, x0, x1      // Multiplication: x4 = x0 * x1
    udiv x5, x0, x1     // Unsigned Division: x5 = x0 / x1

    // Logical operations
    and x6, x0, x1      // Bitwise AND: x6 = x0 & x1
    orr x7, x0, x1      // Bitwise OR: x7 = x0 | x1
    eor x8, x0, x1      // Bitwise XOR: x8 = x0 ^ x1

    // Shift operations
    lsl x9, x0, #2      // Logical Shift Left: x9 = x0 << 2
    lsr x10, x0, #1     // Logical Shift Right: x10 = x0 >> 1
    asr x11, x0, #1     // Arithmetic Shift Right: x11 = x0 >> 1

    // Rotate operation
    ror x12, x0, #2     // Rotate Right: x12 = ROR(x0, 2)

    // Comparison and Conditional Set
    cmp x0, x1          // Compare x0 and x1
    cset x13, gt        // Set x13 to 1 if x0 > x1, else 0

    // Exit syscall
    mov x8, #93         // Syscall number for exit
    mov x0, #0          // Status code 0
    svc #0              // Invoke syscall
```

<figure><img src="https://3864796536-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3fEoxl2Nnfic1jf42ikJ%2Fuploads%2FjOK3kIlteVnEZyV67Thd%2Fimage.png?alt=media&#x26;token=1ed78d39-8989-4c18-a02e-10b3ebb8a21d" alt=""><figcaption></figcaption></figure>

#### 2. Compilation and Debugging Setup

Compile and link:

```bash
as data_processing_instructions.s -o data_processing_instructions.o
ld data_processing_instructions.o -o data_processing_instructions
```

Start gdbserver:

```bash
gdbserver :1234 ./data_processing_instructions
```

Connect with GDB:

```bash
gdb
(gdb) file data_processing_instructions
(gdb) target remote localhost:1234
(gdb) break _start
(gdb) continue
```

#### 3. Detailed Explanation of Each Instruction

1. `mov x0, #10` and `mov x1, #3`
   * These instructions load immediate values into registers.
   * x0 = 10 (binary: 1010), x1 = 3 (binary: 0011)
2. `add x2, x0, x1`
   * Adds the values in x0 and x1, storing the result in x2.
   * Expected result: x2 = 13 (10 + 3)
3. `sub x3, x0, x1`
   * Subtracts x1 from x0, storing the result in x3.
   * Expected result: x3 = 7 (10 - 3)
4. `mul x4, x0, x1`
   * Multiplies x0 by x1, storing the result in x4.
   * Expected result: x4 = 30 (10 \* 3)
5. `udiv x5, x0, x1`
   * Performs unsigned division of x0 by x1, storing the result in x5.
   * Expected result: x5 = 3 (10 / 3, integer division)
6. `and x6, x0, x1`
   * Performs bitwise AND between x0 and x1.
   * 1010 (x0) AND 0011 (x1) = 0010
   * Expected result: x6 = 2
7. `orr x7, x0, x1`
   * Performs bitwise OR between x0 and x1.
   * 1010 (x0) OR 0011 (x1) = 1011
   * Expected result: x7 = 11
8. `eor x8, x0, x1`
   * Performs bitwise XOR between x0 and x1.
   * 1010 (x0) XOR 0011 (x1) = 1001
   * Expected result: x8 = 9
9. `lsl x9, x0, #2`
   * Logically shifts x0 left by 2 bits.
   * 1010 becomes 101000
   * Expected result: x9 = 40 (10 \* 2^2)
10. `lsr x10, x0, #1`
    * Logically shifts x0 right by 1 bit.
    * 1010 becomes 0101
    * Expected result: x10 = 5 (10 / 2)
11. `asr x11, x0, #1`
    * Arithmetically shifts x0 right by 1 bit.
    * For positive numbers, same as LSR.
    * Expected result: x11 = 5
12. `ror x12, x0, #2`
    * Rotates x0 right by 2 bits.
    * 1010 becomes 1010...10 (64-bit rotation)
    * Expected result: x12 = 1073741826 (2^30 + 2)
13. `cmp x0, x1` and `cset x13, gt`
    * Compares x0 and x1, then sets x13 to 1 if x0 > x1, else 0.
    * Expected result: x13 = 1 (because 10 > 3)

#### 4. Debugging Process

Step through each instruction:

```
(gdb) stepi
(gdb) info registers x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13
```

Repeat for each instruction, observing how register values change after each operation.

<figure><img src="https://3864796536-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3fEoxl2Nnfic1jf42ikJ%2Fuploads%2FwyRxLNq0YavDXFIpwUed%2Fimage.png?alt=media&#x26;token=67867d92-fac1-4a29-87ef-88c5057cf8e0" alt=""><figcaption></figcaption></figure>

## 3.3 System Instructions

System Instructions are special commands that allow a program to interact directly with the processor at a system level. These instructions are essential for:

* Operating system operations
* Hardware management
* Maintaining system integrity

They are like the backstage commands that keep everything running smoothly in a computer system.

### 3.3.1 Exception Generation

Exception generation instructions intentionally cause the processor to enter an "exception state." This is useful for:

* System calls (requests to the operating system)
* Debugging
* Handling errors

#### SVC (Supervisor Call)

* **Purpose**: To make system calls (requests to the operating system).
* **Syntax**: `svc #immediate`
*   **Example**:

    ```assembly
    svc #0
    ```
* **Explanation**: When this instruction is executed, it causes the processor to switch to a more privileged execution mode. This allows the operating system to perform tasks that normal user programs cannot do directly, such as accessing hardware or performing critical system functions.

**Practical Example**:

Imagine you are writing a program that needs to read a file from disk. Reading files directly from the disk is a sensitive operation that requires special privileges. By using the `svc #0` instruction, your program requests the operating system to handle the file reading process securely.

#### BRK (Breakpoint)

* **Purpose**: To enter a debugging state.
* **Syntax**: `brk #immediate`
*   **Example**:

    ```assembly
    brk #0
    ```
* **Explanation**: This instruction pauses program execution and enters a debugger if one is attached. It's like setting a breakpoint in your code, which is a common debugging technique to inspect the state of the program at specific points.

**Practical Example**:

If you're developing a complex application and want to check the value of variables at a certain point, you can use the `brk` instruction. When the program execution reaches the `brk` instruction, it will pause, allowing you to inspect the variables' values.

#### HVC (Hypervisor Call)

* **Purpose**: To call hypervisor functions in virtualized environments.
* **Syntax**: `hvc #immediate`
*   **Example**:

    ```assembly
    hvc #0
    ```
* **Explanation**: In systems where multiple operating systems run on the same hardware (virtualization), this instruction allows a guest operating system to request services from the hypervisor, which manages the virtual machines.

In a cloud computing environment, multiple virtual machines (VMs) might run on a single physical server. If a VM needs to perform an operation that requires coordination with the hypervisor (like allocating more memory), it uses the `hvc` instruction to request the hypervisor's assistance.

### 3.3.2 System Control

System control instructions manage the processor state and system registers, which are special storage locations used to control various aspects of the processor's operation.

#### MSR (Move to System Register)

* **Purpose**: To write a value to a system register.
* **Syntax**: `msr <system_register>, <source_register>`
*   **Example**:

    ```assembly
    msr sctlr_el1, x0
    ```
* **Explanation**: This instruction writes the value in register `x0` to the system control register `sctlr_el1`, which is used to control the behavior of the processor at Exception Level 1.

Suppose you need to change the configuration of the CPU's memory management. By writing a specific value to the `sctlr_el1` register, you can enable or disable certain memory features.

#### MRS (Move from System Register)

* **Purpose**: To read a value from a system register.
* **Syntax**: `mrs <destination_register>, <system_register>`
*   **Example**:

    ```assembly
    mrs x0, sctlr_el1
    ```
* **Explanation**: This instruction reads the value from the system control register `sctlr_el1` and stores it in register `x0`.

If you want to check the current configuration of the CPU's memory management, you can read the value from the `sctlr_el1` register into a general-purpose register like `x0` to examine its settings.

### 3.3.3 Cache Maintenance

Cache maintenance instructions manage the processor's cache, which is a small, fast memory used to speed up access to frequently used data.

#### DC (Data Cache operation)

* **Purpose**: To perform operations on the data cache.
* **Common Variants**:
  * `dc cvac`: Clean data cache by virtual address (writes back data from the cache to main memory).
  * `dc ivac`: Invalidate data cache by virtual address (marks data in the cache as invalid).
*   **Example**:

    ```assembly
    dc cvac, x0
    ```
* **Explanation**: This instruction cleans the cache line containing the address in `x0`, meaning it writes the data back to main memory and ensures consistency.

**Practical Example**:

When you modify data in memory, the changes are first made in the cache for speed. To ensure that the changes are saved to the main memory, you can use the `dc cvac` instruction. This is important for data integrity, especially in multi-threaded applications where multiple processes might access the same data.

#### IC (Instruction Cache operation)

* **Purpose**: To perform operations on the instruction cache.
*   **Example**:

    ```assembly
    ic iallu
    ```
* **Explanation**: This instruction invalidates all entries in the instruction cache, meaning it marks them as outdated so that new instructions must be fetched from memory.

**Practical Example**:

After updating the code in memory (e.g., loading a new program or self-modifying code), the instruction cache may still hold old instructions. Using `ic iallu` ensures that the CPU fetches the updated instructions from memory, preventing the execution of outdated code.

### 3.3.4 TLB (Translation Lookaside Buffer) Maintenance

The TLB is a special cache that speeds up the translation of virtual addresses to physical addresses.

#### TLBI (TLB Invalidate)

* **Purpose**: To invalidate entries in the TLB.
*   **Example**:

    ```assembly
    tlbi vmalle1is
    ```
* **Explanation**: This instruction invalidates all TLB entries for the current virtual machine at Exception Level 1, forcing the processor to update its address mappings.

When the virtual-to-physical address mappings change (e.g., when a new program is loaded or the memory layout changes), the TLB needs to be updated. Using `tlbi vmalle1is` ensures that the processor invalidates outdated mappings and fetches the new ones.



## **3.4 Branching and Condition Codes**

### **3.4.1 Condition Codes**

Condition codes are like little flags that our computer uses to remember the result of certain operations. They help us make decisions in our programs. In ARM64, there are four main condition codes:

1. **N (Negative)**: Indicates if the result of the operation is negative.
2. **Z (Zero)**: Indicates if the result of the operation is zero.
3. **C (Carry)**: Indicates if there's a carry out of the most significant bit (useful for unsigned operations).
4. **V (Overflow)**: Indicates if the operation resulted in an overflow (useful for signed operations).

These flags are stored in the PSTATE (Processor State) register.

**How Do We Set These Flags?**

We set these flags using special versions of normal instructions. These versions have an 's' at the end. For example:

```assembly
adds x0, x1, x2   // Add x1 and x2, put the result in x0, and set flags
subs x0, x1, x2   // Subtract x2 from x1, put the result in x0, and set flags
```

We can also set flags using the compare instruction:

```assembly
cmp x0, x1        // Compare x0 and x1, setting flags based on the result
```

&#x20;**A Simple Example**

Let's look at a basic example to understand how these flags are set:

File: `condition_flags.s`

```assembly
.global _start
.section .text

_start:
    // Initialize registers
    mov x0, #5
    mov x1, #3

    // Perform subtraction and set flags
    subs x2, x0, x1   // x2 = x0 - x1, and set flags

    // Infinite loop to stop execution
    b .
```

<figure><img src="https://3864796536-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3fEoxl2Nnfic1jf42ikJ%2Fuploads%2FfYP9LsBn4RuFv9JG9Y4f%2Fimage.png?alt=media&#x26;token=e03f6a49-6621-4c8a-af1b-a8a7a90ca169" alt=""><figcaption></figcaption></figure>

\
Explanation:

* **Initialize registers**: We set `x0` to 5 and `x1` to 3.
* **Perform subtraction and set flags**: The `subs` instruction subtracts `x1` from `x0`, stores the result in `x2`, and sets the condition flags based on the result.
* **Infinite loop**: The `b .` instruction creates an infinite loop, causing the program to repeatedly branch to itself. This halts execution so we can inspect the state of the registers and flags in GDB.

**Checking Flags in GDB**

To see the condition flags in action, we can use GDB:

1.  **Assemble and Link the Program**:

    ```bash
    as condition_flags.s -o condition_flags.o
    ld condition_flags.o -o condition_flags
    ```
2.  **Start GDB Server**:

    ```bash
    gdbserver :1234 ./condition_flags
    ```
3.  **Start GDB and Connect to the Server**: Open a new terminal and start GDB:

    ```bash
    gdb
    ```
4.  **Load the Program in GDB**:

    ```gdb
    (gdb) file condition_flags
    ```
5.  **Connect to the Remote Target**:

    ```gdb
    (gdb) target remote localhost:1234
    ```
6.  **Step Through the Program**:

    ```gdb
    (gdb) stepi  // Step to 'mov x0, #5'
    (gdb) stepi  // Step to 'mov x1, #3'
    (gdb) stepi  // Step to 'subs x2, x0, x1'
    (gdb) info registers cpsr
    ```

    Check the condition flags in the `cpsr` register.

<figure><img src="https://3864796536-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3fEoxl2Nnfic1jf42ikJ%2Fuploads%2F0hRvqK6p9AJa9HVZ8omy%2Fimage.png?alt=media&#x26;token=14ef6d85-6ecb-4f59-99b5-4bdab2accd54" alt=""><figcaption></figcaption></figure>

8. **Check CPSR Register**:

```gdb
(gdb) info registers cpsr
```

This should show something like:

```
cpsr           0x20201000          [ EL=0 BTYPE=0 SSBS SS C ]
```

The CPSR register in GDB will show the condition flags. The condition flags are represented by specific bits in the CPSR register:

* N: Bit 31
* Z: Bit 30
* C: Bit 29
* V: Bit 28

For example, if the CPSR value is `0x20201000`, you can interpret the flags as follows:

* **N** (Negative): Bit 31 = 0 (not set)
* **Z** (Zero): Bit 30 = 0 (not set)
* **C** (Carry): Bit 29 = 1 (set)
* **V** (Overflow): Bit 28 = 0 (not set)

**Understanding CPSR**

The CPSR (Current Program Status Register) contains the condition flags as part of its bits. You can view the CPSR value in GDB and decode the flags from it.

Example:

1.  **Check CPSR Register Value**:

    ```gdb
    (gdb) info registers cpsr
    cpsr           0x20201000          [ EL=0 BTYPE=0 SSBS SS C ]
    ```
2. **Binary Representation**: Convert the CPSR value to its binary form. For example, `0x20201000` in binary is `0010 0000 0010 0000 0001 0000 0000 0000`.
3. **Extract Condition Flags**:
   * **N** (Negative): Bit 31 = 0 (not set)
   * **Z** (Zero): Bit 30 = 0 (not set)
   * **C** (Carry): Bit 29 = 1 (set)
   * **V** (Overflow): Bit 28 = 0 (not set)

### **3.4.2 Branching**

Branching is a fundamental concept in programming that allows the flow of execution to change based on certain conditions. In ARM64 assembly, branching is crucial for implementing control structures like if-else statements, loops, and switch cases.\
\
Branching is like making a decision in your code. It's how we tell the computer to do different things based on certain conditions.

Think of it like a fork in a road:

* If it's sunny, go to the beach.
* If it's raining, stay home.

In assembly, we use branches to create these decision points.

In ARM64, branching instructions are used to jump to different parts of the program. The main types of branching instructions are:

1. **Unconditional Branch**: Always jumps to the specified label.
2. **Conditional Branch**: Jumps to the specified label only if certain conditions are met.

**1. Unconditional Branch**

An unconditional branch always jumps to the specified label, regardless of any condition flags. It is used to transfer control unconditionally to another part of the program.

**Example:**

```assembly
.global _start
.section .text

_start:
    mov x0, #1        // Move 1 into register x0
    b target_label    // Unconditionally branch to target_label
    mov x0, #2        // This instruction will not execute

target_label:
    mov x1, #3        // Move 3 into register x1
```

Explanation:

* `b target_label` is an unconditional branch. The program always jumps to `target_label`.
* The instruction `mov x0, #2` will not execute because the branch instruction `b target_label` is executed first.

&#x20;**2. Common Conditional Branches:**

#### 1. **B.eq (branch if equal)**

**Explanation**:

* **B.eq**: Jumps to the specified label if the Zero (Z) flag is set.
* The Zero (Z) flag is set when the result of a comparison is zero, meaning the operands are equal.

**Example**:

```assembly
.global _start
.section .text

_start:
    mov x0, #5        // Move 5 into register x0
    mov x1, #5        // Move 5 into register x1

    cmp x0, x1        // Compare x0 and x1, setting condition flags

    b.eq equal        // Branch to 'equal' if x0 == x1

    // This part executes if x0 != x1
    mov x2, #0        // Set x2 to 0 (not equal)
    b end             // Unconditionally branch to 'end'

equal:
    mov x2, #1        // Set x2 to 1 (equal)

end:
    b .               // Infinite loop to stop execution
```

**Detailed Explanation**:

1. **mov x0, #5** and **mov x1, #5**:
   * Set `x0` to 5 and `x1` to 5.
   * Registers: `x0 = 5`, `x1 = 5`
2. **cmp x0, x1**:
   * Compares `x0` and `x1`. Since `x0` equals `x1`, the Zero (Z) flag is set.
   * Registers: `x0 = 5`, `x1 = 5`
   * Flags: `Z = 1`
3. **b.eq equal**:
   * Branches to the `equal` label if the Zero (Z) flag is set.
   * Since the Z flag is set, the program jumps to the `equal` label.
4. **equal**:
   * The branch is taken, so `x2` is set to 1, indicating `x0` equals `x1`.
   * Registers: `x2 = 1`
5. **end**:
   * The program reaches the `end` label and enters an infinite loop, stopping execution.
   * The program does not execute any further instructions.

#### 2. **B.ne (branch if not equal)**

**Explanation**:

* **B.ne**: Jumps to the specified label if the Zero (Z) flag is not set.
* The Zero (Z) flag is not set when the result of a comparison is not zero, meaning the operands are not equal.

**Example**:

```assembly
.global _start
.section .text

_start:
    mov x0, #5        // Move 5 into register x0
    mov x1, #3        // Move 3 into register x1

    cmp x0, x1        // Compare x0 and x1, setting condition flags

    b.ne not_equal    // Branch to 'not_equal' if x0 != x1

    // This part executes if x0 == x1
    mov x2, #0        // Set x2 to 0 (equal)
    b end             // Unconditionally branch to 'end'

not_equal:
    mov x2, #1        // Set x2 to 1 (not equal)

end:
    b .               // Infinite loop to stop execution
```

**Detailed Explanation**:

1. **mov x0, #5** and **mov x1, #3**:
   * Set `x0` to 5 and `x1` to 3.
   * Registers: `x0 = 5`, `x1 = 3`
2. **cmp x0, x1**:
   * Compares `x0` and `x1`. Since `x0` does not equal `x1`, the Zero (Z) flag is not set.
   * Registers: `x0 = 5`, `x1 = 3`
   * Flags: `Z = 0`
3. **b.ne not\_equal**:
   * Branches to the `not_equal` label if the Zero (Z) flag is not set.
   * Since the Z flag is not set, the program jumps to the `not_equal` label.
4. **not\_equal**:
   * The branch is taken, so `x2` is set to 1, indicating `x0` does not equal `x1`.
   * Registers: `x2 = 1`
5. **end**:
   * The program reaches the `end` label and enters an infinite loop, stopping execution.
   * The program does not execute any further instructions.

#### 3. **B.lt (branch if less than)**

**Explanation**:

* **B.lt**: Jumps to the specified label if the Negative (N) flag is not equal to the Overflow (V) flag.
* This indicates that the first operand is less than the second operand in signed comparison.

**Example**:

```assembly
.global _start
.section .text

_start:
    mov x0, #3        // Move 3 into register x0
    mov x1, #5        // Move 5 into register x1

    cmp x0, x1        // Compare x0 and x1, setting condition flags

    b.lt less_than    // Branch to 'less_than' if x0 < x1

    // This part executes if x0 >= x1
    mov x2, #0        // Set x2 to 0 (not less than)
    b end             // Unconditionally branch to 'end'

less_than:
    mov x2, #1        // Set x2 to 1 (less than)

end:
    b .               // Infinite loop to stop execution
```

**Detailed Explanation**:

1. **mov x0, #3** and **mov x1, #5**:
   * Set `x0` to 3 and `x1` to 5.
   * Registers: `x0 = 3`, `x1 = 5`
2. **cmp x0, x1**:
   * Compares `x0` and `x1`. Since `x0` is less than `x1`, the Negative (N) flag is set.
   * Registers: `x0 = 3`, `x1 = 5`
   * Flags: `N = 1`, `V = 0`
3. **b.lt less\_than**:
   * Branches to the `less_than` label if the Negative (N) flag is not equal to the Overflow (V) flag.
   * Since N is not equal to V, the program jumps to the `less_than` label.
4. **less\_than**:
   * The branch is taken, so `x2` is set to 1, indicating `x0` is less than `x1`.
   * Registers: `x2 = 1`
5. **end**:
   * The program reaches the `end` label and enters an infinite loop, stopping execution.
   * The program does not execute any further instructions.

#### 4. **B.le (branch if less than or equal)**

**Explanation**:

* **B.le**: Jumps to the specified label if the Zero (Z) flag is set or the Negative (N) flag is not equal to the Overflow (V) flag.
* This indicates that the first operand is less than or equal to the second operand in signed comparison.

**Example**:

```assembly
.global _start
.section .text

_start:
    mov x0, #3        // Move 3 into register x0
    mov x1, #5        // Move 5 into register x1

    cmp x0, x1        // Compare x0 and x1, setting condition flags

    b.le less_or_equal  // Branch to 'less_or_equal' if x0 <= x1

    // This part executes if x0 > x1
    mov x2, #0          // Set x2 to 0 (not less than or equal)
    b end               // Unconditionally branch to 'end'

less_or_equal:
    mov x2, #1          // Set x2 to 1 (less than or equal)

end:
    b .                 // Infinite loop to stop execution
```

**Detailed Explanation**:

1. **mov x0, #3** and **mov x1, #5**:
   * Set `x0` to 3 and `x1` to 5.
   * Registers: `x0 = 3`, `x1 = 5`
2. **cmp x0, x1**:
   * Compares `x0` and `x1`. Since `x0` is less than `x1`, the Negative (N) flag is set.
   * Registers: `x0 = 3`, `x1 = 5`
   * Flags: `N = 1`, `V = 0`
3. **b.le less\_or\_equal**:
   * Branches to the `less_or_equal` label if the Zero (Z) flag is set or the Negative (N) flag is not equal to the Overflow (V) flag.
   * Since N is not equal to V, the program jumps to

the `less_or_equal` label. 4. **less\_or\_equal**: - The branch is taken, so `x2` is set to 1, indicating `x0` is less than or equal to `x1`. - Registers: `x2 = 1` 5. **end**: - The program reaches the `end` label and enters an infinite loop, stopping execution. - The program does not execute any further instructions.

#### 5. **B.gt (branch if greater than)**

**Explanation**:

* **B.gt**: Jumps to the specified label if the Zero (Z) flag is not set and the Negative (N) flag is equal to the Overflow (V) flag.
* This indicates that the first operand is greater than the second operand in signed comparison.

**Example**:

```assembly
.global _start
.section .text

_start:
    mov x0, #5        // Move 5 into register x0
    mov x1, #3        // Move 3 into register x1

    cmp x0, x1        // Compare x0 and x1, setting condition flags

    b.gt greater_than // Branch to 'greater_than' if x0 > x1

    // This part executes if x0 <= x1
    mov x2, #0        // Set x2 to 0 (not greater than)
    b end             // Unconditionally branch to 'end'

greater_than:
    mov x2, #1        // Set x2 to 1 (greater than)

end:
    b .               // Infinite loop to stop execution
```

**Detailed Explanation**:

1. **mov x0, #5** and **mov x1, #3**:
   * Set `x0` to 5 and `x1` to 3.
   * Registers: `x0 = 5`, `x1 = 3`
2. **cmp x0, x1**:
   * Compares `x0` and `x1`. Since `x0` is greater than `x1`, the Zero (Z) flag is not set and the Negative (N) flag is equal to the Overflow (V) flag.
   * Registers: `x0 = 5`, `x1 = 3`
   * Flags: `Z = 0`, `N = 0`, `V = 0`
3. **b.gt greater\_than**:
   * Branches to the `greater_than` label if the Zero (Z) flag is not set and the Negative (N) flag is equal to the Overflow (V) flag.
   * Since Z is 0 and N is equal to V, the program jumps to the `greater_than` label.
4. **greater\_than**:
   * The branch is taken, so `x2` is set to 1, indicating `x0` is greater than `x1`.
   * Registers: `x2 = 1`
5. **end**:
   * The program reaches the `end` label and enters an infinite loop, stopping execution.
   * The program does not execute any further instructions.

#### 6. **B.ge (branch if greater than or equal)**

**Explanation**:

* **B.ge**: Jumps to the specified label if the Negative (N) flag is equal to the Overflow (V) flag.
* This indicates that the first operand is greater than or equal to the second operand in signed comparison.

**Example**:

```assembly
.global _start
.section .text

_start:
    mov x0, #5        // Move 5 into register x0
    mov x1, #3        // Move 3 into register x1

    cmp x0, x1        // Compare x0 and x1, setting condition flags

    b.ge greater_or_equal // Branch to 'greater_or_equal' if x0 >= x1

    // This part executes if x0 < x1
    mov x2, #0            // Set x2 to 0 (not greater than or equal)
    b end                 // Unconditionally branch to 'end'

greater_or_equal:
    mov x2, #1            // Set x2 to 1 (greater than or equal)

end:
    b .                   // Infinite loop to stop execution
```

**Detailed Explanation**:

1. **mov x0, #5** and **mov x1, #3**:
   * Set `x0` to 5 and `x1` to 3.
   * Registers: `x0 = 5`, `x1 = 3`
2. **cmp x0, x1**:
   * Compares `x0` and `x1`. Since `x0` is greater than `x1`, the Negative (N) flag is equal to the Overflow (V) flag.
   * Registers: `x0 = 5`, `x1 = 3`
   * Flags: `N = 0`, `V = 0`
3. **b.ge greater\_or\_equal**:
   * Branches to the `greater_or_equal` label if the Negative (N) flag is equal to the Overflow (V) flag.
   * Since N is equal to V, the program jumps to the `greater_or_equal` label.
4. **greater\_or\_equal**:
   * The branch is taken, so `x2` is set to 1, indicating `x0` is greater than or equal to `x1`.
   * Registers: `x2 = 1`
5. **end**:
   * The program reaches the `end` label and enters an infinite loop, stopping execution.
   * The program does not execute any further instructions.

#### Example Program: `branching_example.s`

```assembly
.global _start
.section .text

_start:
    // Initialize registers
    mov x0, #5        // Set x0 to 5
    mov x1, #5        // Set x1 to 5

    cmp x0, x1        // Compare x0 and x1, setting condition flags

    b.eq equal        // Branch to 'equal' if x0 == x1

    // This part executes if x0 != x1
    mov x2, #0        // Set x2 to 0 (x0 != x1)
    b end             // Branch to 'end'

equal:
    mov x2, #1        // Set x2 to 1 (x0 == x1)

    // Modify x0 and x1 to test other conditions
    mov x0, #3        // Set x0 to 3
    mov x1, #5        // Set x1 to 5

    cmp x0, x1        // Compare x0 and x1, setting condition flags
    b.lt less_than    // Branch to 'less_than' if x0 < x1

    mov x3, #0        // Set x3 to 0 (x0 >= x1)
    b end             // Branch to 'end'

less_than:
    mov x3, #1        // Set x3 to 1 (x0 < x1)

    // Modify x0 and x1 to test another condition
    mov x0, #10       // Set x0 to 10
    mov x1, #5        // Set x1 to 5

    cmp x0, x1        // Compare x0 and x1, setting condition flags
    b.gt greater_than // Branch to 'greater_than' if x0 > x1

    mov x4, #0        // Set x4 to 0 (x0 <= x1)
    b end             // Branch to 'end'

greater_than:
    mov x4, #1        // Set x4 to 1 (x0 > x1)

end:
    b .               // Infinite loop to stop execution
```

#### Steps to Compile, Run, and Debug

1. **Save the program**: Save the above code to a file named `branching_example.s`.
2.  **Assemble the program**:

    ```bash
    as branching_example.s -o branching_example.o
    ```
3.  **Link the program**:

    ```bash
    ld branching_example.o -o branching_example
    ```
4.  **Start GDB Server**:

    ```bash
    gdbserver :1234 ./branching_example
    ```



    <figure><img src="https://3864796536-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3fEoxl2Nnfic1jf42ikJ%2Fuploads%2FbYPzoC22lB6F96IwSZsp%2Fimage.png?alt=media&#x26;token=4bddaa5f-0dfe-4a4e-b0e0-9348dc950ec9" alt=""><figcaption></figcaption></figure>
5.  **Start GDB and Connect to the Server**: Open a new terminal and start GDB:

    ```bash
    gdb
    ```
6.  **Load the Program in GDB**:

    ```gdb
    (gdb) file branching_example
    ```
7.  **Connect to the Remote Target**:

    ```gdb
    (gdb) target remote localhost:1234
    ```

<figure><img src="https://3864796536-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3fEoxl2Nnfic1jf42ikJ%2Fuploads%2FzVxzl9Q9blt7A59ptW04%2Fimage.png?alt=media&#x26;token=bef554c4-1ec0-47a4-8b59-75ecabbaa30d" alt=""><figcaption></figcaption></figure>

#### Step-by-Step Debugging with Explanations

1.  **Initial Setup**:

    ```gdb
    (gdb) stepi  # Step into 'mov x0, #5'
    (gdb) info registers x0
    ```

    Registers: `x0 = 5`
2.  **Setting x1**:

    ```gdb
    (gdb) stepi  # Step into 'mov x1, #5'
    (gdb) info registers x1
    ```

    Registers: `x1 = 5`
3.  **Compare x0 and x1**:

    ```gdb
    (gdb) stepi  # Step into 'cmp x0, x1'
    (gdb) info registers cpsr
    ```

    * **Explanation**: Compares `x0` and `x1`. Since `x0` equals `x1`, the Zero (Z) flag is set.
    * Registers: `x0 = 5`, `x1 = 5`
    *   Flags: `Z = 1`

        <figure><img src="https://3864796536-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3fEoxl2Nnfic1jf42ikJ%2Fuploads%2FpC4fmJhvyReelL5mdQX3%2Fimage.png?alt=media&#x26;token=a14e8c7f-7448-4c1d-98b0-a80a383dc1c8" alt=""><figcaption></figcaption></figure>
4.  **Branch if Equal**:

    ```gdb
    (gdb) stepi  # Step into 'b.eq equal'
    ```

    * **Explanation**: Branches to the `equal` label if the Zero (Z) flag is set.
    *   Since the Z flag is set (Z = 1), the program jumps to the `equal` label.

        <figure><img src="https://3864796536-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3fEoxl2Nnfic1jf42ikJ%2Fuploads%2FmF5oKOCGKjbH3jSLxfZI%2Fimage.png?alt=media&#x26;token=f9c8da05-68b1-492e-839f-d21cc2c67b62" alt=""><figcaption></figcaption></figure>
5.  **Setting x2 at the `equal` label**:

    ```gdb
    (gdb) stepi  # Step into 'mov x2, #1'
    (gdb) info registers x2
    ```

    * **Explanation**: The branch is taken, so `x2` is set to 1, indicating `x0` equals `x1`.
    * Registers: `x2 = 1`
6.  **Modify x0 and x1 for less than comparison**:

    ```gdb
    (gdb) stepi  # Step into 'mov x0, #3'
    (gdb) stepi  # Step into 'mov x1, #5'
    (gdb) info registers x0 x1
    ```

    Registers: `x0 = 3`, `x1 = 5`
7.  **Compare x0 and x1 for less than**:

    ```gdb
    (gdb) stepi  # Step into 'cmp x0, x1'
    (gdb) info registers cpsr
    ```

    * **Explanation**: Compares `x0` and `x1`. Since `x0` is less than `x1`, the Negative (N) flag is set.
    * Registers: `x0 = 3`, `x1 = 5`
    * Flags: `N = 1`, `V = 0`
8.  **Branch if Less Than**:

    ```gdb
    (gdb) stepi  # Step into 'b.lt less_than'
    ```

    * **Explanation**: Branches to the `less_than` label if the Negative (N) flag is set.
    * Since N is set, the program jumps to the `less_than` label.
9.  **Setting x3 at the `less_than` label**:

    ```gdb
    (gdb) stepi  # Step into 'mov x3, #1'
    (gdb) info registers x3
    ```

    * **Explanation**: The branch is taken, so `x3` is set to 1, indicating `x0` is less than `x1`.
    * Registers: `x3 = 1`
10. **Modify x0 and x1 for greater than comparison**:

    ```gdb
    (gdb) stepi  # Step into 'mov x0, #10'
    (gdb) stepi  # Step into 'mov x1, #5'
    (gdb) info registers x0 x1
    ```

    Registers: `x0 = 10`, `x1 = 5`
11. **Compare x0 and x1 for greater than**:

    ```gdb
    (gdb) stepi  # Step into 'cmp x0, x1'
    (gdb) info registers cpsr
    ```

    * **Explanation**: Compares `x0` and `x1`. Since `x0` is greater than `x1`, the Zero (Z) flag is not set and the Negative (N) flag is clear.
    * Registers: `x0 = 10`, `x1 = 5`
    * Flags: `Z = 0`, `N = 0`, `V = 0`
12. **Branch if Greater Than**:

    ```gdb
    (gdb) stepi  # Step into 'b.gt greater_than'
    ```

    * **Explanation**: Branches to the `greater_than` label if the Zero (Z) flag is not set and the Negative (N) flag is equal to the Overflow (V) flag.
    * Since Z is 0 and N is equal to V, the program jumps to the `greater_than` label.
13. **Setting x4 at the `greater_than` label**:

    ```gdb
    (gdb) stepi  # Step into 'mov x4, #1'
    (gdb) info registers x4
    ```

    * **Explanation**: The branch is taken, so `x4` is set to 1, indicating `x0` is greater than `x1`.
    * Registers: `x4 = 1`
14. **End and Infinite Loop**:

    ```gdb
    (gdb) stepi  # Step into 'end'
    (gdb) stepi  # Infinite loop at 'b .'
    ```

#### Summary of the Program Execution:

1. **Initial Comparison**:
   * `x0 = 5`, `x1 = 5`
   * \`cmp x0, x

1`sets`Z = 1 `- Branches to`label\_equal`, sets` x2 = 1\`

2. **Less Than Comparison**:
   * `x0 = 3`, `x1 = 5`
   * `cmp x0, x1` sets `N = 1`
   * Branches to `label_less_than`, sets `x3 = 1`
3. **Greater Than Comparison**:
   * `x0 = 10`, `x1 = 5`
   * `cmp x0, x1` sets `Z = 0`, `N = 0`, `V = 0`
   *   Branches to `label_greater_than`, sets `x4 = 1`

       <figure><img src="https://3864796536-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F3fEoxl2Nnfic1jf42ikJ%2Fuploads%2F6hQ2bYPcT4KN0RkYpH7J%2Fimage.png?alt=media&#x26;token=b2b0b5ab-eb08-4437-9e99-f0cb897d07e4" alt=""><figcaption></figcaption></figure>
4. **End**:
   * The program reaches the `end` label and enters an infinite loop.



