gpt4 book ai didi

C-宏 : set a register field defined by a bit-mask to a given value

转载 作者:行者123 更新时间:2023-12-04 11:03:53 24 4
gpt4 key购买 nike

我有 32 位寄存器,其字段定义为位掩码,例如

#define BM_TEST_FIELD 0x000F0000

我需要一个宏,它允许我将寄存器(由其地址定义)的字段(由其位掩码定义)设置为给定值。这是我想出的:
#include <stdio.h>
#include <assert.h>

typedef unsigned int u32;

/*
* Set a given field defined by a bit-mask MASK of a 32-bit register at address
* ADDR to a value VALUE.
*/
#define SET_REGISTER_FIELD(ADDR, MASK, VALUE) \
{ \
u32 mask=(MASK); u32 value=(VALUE); \
u32 mem_reg = *(volatile u32*)(ADDR); /* Get current register value */ \
assert((MASK) != 0); /* Null masks are not supported */ \
while(0 == (mask & 0x01)) /* Shift the value to the left until */ \
{ /* it aligns with the bit field */ \
mask = mask >> 1; value = value << 1; \
} \
mem_reg &= ~(MASK); /* Clear previous register field value */ \
mem_reg |= value; /* Update register field with new value */ \
*(volatile u32*)(ADDR) = mem_reg; /* Update actual register */ \
}

/* Test case */
#define BM_TEST_FIELD 0x000F0000
int main()
{
u32 reg = 0x12345678;
printf("Register before: 0x%.8X\n", reg);/* should be 0x12345678 */
SET_REGISTER_FIELD(&reg, BM_TEST_FIELD, 0xA);
printf("Register after: 0x%.8X\n", reg); /* should be 0x123A5678 */
return 0;
}

有没有更简单的方法来做到这一点?

EDIT :特别是,我正在寻找一种方法来减少运行时计算要求。有没有办法让预处理器计算值所需的左移次数?

最佳答案

EDIT: in particular, I'm looking for a way to do reduce the run-time computing requirements. Is there a way to have the pre-processor compute the number of required left-shifts for the value?



是的:
value *= ((MASK) & ~((MASK) << 1))

这乘以 value通过 MASK 中的最低设置位.已知乘数在编译时是 2 的常数幂,因此这将被任何远程正常的编译器编译为简单的左移。

关于C-宏 : set a register field defined by a bit-mask to a given value,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2915037/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com