STM32 Flash对齐技巧详解
这行代码 uint32_t aligned_address = (address + 3) & ~0x03; 是一个经典的位运算技巧,用于将任意地址值向上取整为 4 的倍数。下面从原理到示例详细解释:
一、核心目标:向上对齐到 4 的倍数
0x08010001 → 输出 0x080100040x08010004 → 输出 0x08010004(已对齐,保持不变)二、位运算拆解:(address + 3) & ~0x03
1. ~0x03 的含义
0x03 的二进制是 0000 0011~0x03 变为 1111 1100(即 0xFFFC)2. address + 3 的作用
0x08010001),加 3 后会进入下一个 4 的倍数区间0x08010004),加 3 后仍在下一个 4 的倍数区间的边界内3. & ~0x03 的作用
1111 1100 按位与,清除地址的最低 2 位(即模 4 的余数部分)三、示例验证
示例 1:输入 0x08010001(未对齐)
- 加 3:
0x08010001 + 3 = 0x08010004 - 按位与:
0x08010004 & 0xFFFC = 0x08010004 - 二进制过程:
0x08010004 → 0000 1000 0000 0001 0000 0000 0000 0100 0xFFFC → 1111 1111 1111 1100 ----------------------------------- 结果 → 0000 1000 0000 0001 0000 0000 0000 0100 → 0x08010004
示例 2:输入 0x08010004(已对齐)
- 加 3:
0x08010004 + 3 = 0x08010007 - 按位与:
0x08010007 & 0xFFFC = 0x08010004 - 二进制过程:
0x08010007 → 0000 1000 0000 0001 0000 0000 0000 0111 0xFFFC → 1111 1111 1111 1100 ----------------------------------- 结果 → 0000 1000 0000 0001 0000 0000 0000 0100 → 0x08010004
示例 3:输入 0x08010003(边界值)
- 加 3:
0x08010003 + 3 = 0x08010006 - 按位与:
0x08010006 & 0xFFFC = 0x08010004 - 二进制过程:
0x08010006 → 0000 1000 0000 0001 0000 0000 0000 0110 0xFFFC → 1111 1111 1111 1100 ----------------------------------- 结果 → 0000 1000 0000 0001 0000 0000 0000 0100 → 0x08010004
四、数学原理
对于任意整数 x,向上取整到 n 的倍数可以表示为:
ceil(x / n) * n
位运算技巧:当 n 是 2 的幂(如 4、8、16)时,可以简化为:
(x + (n-1)) & ~(n-1)
推导过程:
n-1的二进制形式是低位全 1(如0x03→0000 0011)~(n-1)的二进制形式是低位全 0,高位全 1(如0xFFFC→1111 1100)(x + (n-1))将值偏移到下一个区间& ~(n-1)清除低位,得到对齐结果
五、通用公式
| 对齐目标 | 代码实现 | 示例(输入→输出) |
|---|---|---|
| 4 字节对齐 | (x + 3) & ~0x03 |
5 → 8, 8 → 8 |
| 8 字节对齐 | (x + 7) & ~0x07 |
10 → 16, 16 → 16 |
| 16 字节对齐 | (x + 15) & ~0x0F |
20 → 32, 32 → 32 |
六、在 STM32 Flash 编程中的应用
当你需要在任意地址写入 32 位数据时,可先对齐地址:
uint32_t address = 0x08010001; // 未对齐的地址
uint32_t aligned_addr = (address + 3) & ~0x03; // 对齐到0x08010004
// 安全写入
FLASH_ProgramWord(aligned_addr, 0x12345678);
七、注意事项
- 仅适用于 2 的幂对齐:该技巧只对
n=2^k有效(如 4、8、16) - 数据类型匹配:32 位对齐适用于
FLASH_ProgramWord(),16 位对齐适用于FLASH_ProgramHalfWord() - 溢出风险:如果
address接近UINT32_MAX,加 3 可能导致溢出(实际应用中 Flash 地址远小于此值,通常安全)
掌握这种位运算对齐技巧,能帮助你高效处理 STM32 Flash 编程中的地址约束问题。
作者:weixin_58038206