Extract and Modify Field in a 32-bit Register

Code

#include <stdio.h>
#include <stdint.h>

#define EXTRACT_START_POS   10U
#define EXTRACT_END_POS     14U

#define POS_MASK(val)       ((1 << (val + 1)) - 1)

// Define macros here
#define EXTRACT_DATA(val)   (uint32_t)((val & (POS_MASK(EXTRACT_END_POS) << EXTRACT_START_POS)) >> EXTRACT_START_POS)
#define REMOVE_DATA(val)    (uint32_t)(val & ~(POS_MASK(EXTRACT_END_POS) << EXTRACT_START_POS))

uint32_t update_register(uint32_t reg) 
{
    uint32_t res_reg = REMOVE_DATA(reg);
    uint32_t temp_reg = EXTRACT_DATA(reg);

    if (temp_reg < 31)
    {
        temp_reg += 1;
    }

    res_reg |= (temp_reg << EXTRACT_START_POS);

    return res_reg;
}

int main() 
{
    uint32_t reg;
    scanf("%u", &reg);
    uint32_t updated = update_register(reg);
    printf("%u", updated);
    return 0;
}

Solving Approach

This program demonstrates a common "Read-Modify-Write" sequence used in firmware development to manipulate a specific bit field within a 32-bit register without affecting the surrounding data.

1. Bit Field Layout

The code targets a specific section of a uint32_t register defined by a window:

  • Start Position: Bit 10

  • End Position: Bit 14

  • Width: 5 bits (capable of holding values from 0 to 31)

2. How the Logic Works

The process is divided into three distinct phases to ensure "data isolation":

Phase A: Data Extraction (EXTRACT_DATA)

To read the value, the program creates a mask for the window and performs a Bitwise AND. It then uses a Right Shift (>>) to move those bits down to the "0" position. This converts the raw bits into a human-readable integer (0–31).

Phase B: Clearing the Slot (REMOVE_DATA)

Before updating, the old data must be "erased." The program creates a mask for the 10–14 bit range, flips it using the Bitwise NOT (~) operator, and ANDs it with the original register. This sets only the bits in that specific 5-bit window to zero while preserving all other bits in the register.

Phase C: The Update Logic

The function update_register performs a safe increment:

  1. It extracts the current 5-bit value.

  2. It checks if the value is less than 31 (the maximum value a 5-bit field can hold).

  3. If safe, it increments the value by 1.

  4. It shifts the new value back to position 10 and uses a Bitwise OR (|) to "stamp" it into the cleared slot.

3. Key Technical Advantages

  • Non-Destructive: By using the REMOVE_DATA logic, the program ensures that bits 0–9 and 15–31 remain completely unchanged. This is critical when a register controls multiple hardware features simultaneously.

  • Overflow Protection: The if (temp_reg < 31) check prevents a "rollover" where incrementing 31 would accidentally result in 0 or corrupt adjacent bit fields.

  • Efficiency: The operations use direct CPU instructions (AND, OR, NOT, SHIFT), making the update extremely fast and suitable for real-time embedded systems.

Summary Table for Developers

Operation

Logical Result

Bitwise Equivalent

Masking

Isolates the window

(reg & Mask)

Clearing

Sets window to 0

(reg & ~Mask)

Inserting

Writes new data(reg
Upvote
Downvote
Loading...

Input

15360

Expected Output

16384