Универсальная функция (для pos8 16 и 24):
uint32_t setb(uint32_t val, uint8_t a, int pos)
{
val &= ~(0xffUL << pos);
val |= (uint32_t)a << pos;
return val;
}
Если вам не нравятся сдвиги:
uint32_t f(uint8_t a, uint8_t b,uint8_t c,uint8_t d) {
return a + 0x100UL * b + 0x10000UL * c + 0x1000000UL * d;
}
, любой хороший оптимизирующий компилятор сгенерирует очень эффективный код:
gcc ARM
f:
add r0, r0, r2, lsl #16
add r0, r0, r3, lsl #24
add r0, r0, r1, lsl #8
bx lr
clang x86
f: # @f
shl esi, 8
lea eax, [rsi + rdi]
shl edx, 16
or eax, edx
shl ecx, 24
or eax, ecx
ret
Только на очень маленьких микросхемах я бы порекомендовал способ объединения
uint32_t g(uint8_t a, uint8_t b,uint8_t c,uint8_t d)
{
union
{
uint32_t v32;
uint8_t v8[4];
}x = {.v8[0] = a, .v8[1] = b, .v8[2] = c, .v8[3] = d};
return x.v32;
}
, поскольку это проще дляэто оптимизировать:
__zero_reg__ = 1
f:
push r16
push r17
ldi r25,lo8(0)
ldi r26,lo8(0)
ldi r27,hi8(0)
add r24,r22
adc r25,__zero_reg__
adc r26,__zero_reg__
adc r27,__zero_reg__
ldi r21,lo8(0)
subi r20,lo8(-(8))
sbci r21,hi8(-(8))
rjmp 2f
1: lsl r24
rol r25
rol r26
rol r27
2: dec r20
brpl 1b
ldi r19,lo8(0)
subi r18,lo8(-(16))
sbci r19,hi8(-(16))
rjmp 2f
1: lsl r24
rol r25
rol r26
rol r27
2: dec r18
brpl 1b
mov r19,r24
clr r18
clr r17
clr r16
mov r22,r16
mov r23,r17
mov r24,r18
mov r25,r19
pop r17
pop r16
ret
g:
push r16
push r17
mov r25,r18
mov r17,r22
mov r22,r24
mov r23,r17
mov r24,r20
pop r17
pop r16
ret