#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", ®);
uint32_t updated = update_register(reg);
printf("%u", updated);
return 0;
}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.
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)
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:
It extracts the current 5-bit value.
It checks if the value is less than 31 (the maximum value a 5-bit field can hold).
If safe, it increments the value by 1.
It shifts the new value back to position 10 and uses a Bitwise OR (|) to "stamp" it into the cleared slot.
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.
Operation | Logical Result | Bitwise Equivalent |
|---|---|---|
Masking | Isolates the window |
|
Clearing | Sets window to 0 |
|
Inserting | Writes new data | (reg |
Input
15360
Expected Output
16384