asm_book/section_2/bitfields/test.c
2022-06-18 11:32:19 -05:00

70 lines
1.6 KiB
C

#include <stdio.h>
struct BF {
unsigned char a : 1;
unsigned char b : 2;
unsigned char c : 5;
};
unsigned char noBF = 0;
//#define C
#undef C
#ifdef C
/* Note the absence of defensive programming such as checking
to ensure that byte is not null and that bit_number is not
too large.
*/
void ClearA(unsigned char * byte) {
*byte &= ~1;
}
void SetA(unsigned char * byte) {
*byte &= ~1;
*byte |= 1;
}
void ClearB(unsigned char * byte) {
*byte &= ~6;
}
void SetB(unsigned char * byte, unsigned char value) {
value &= 3; // ensures only bits 0 and 1 can be set
*byte &= ~6; // clears bits 1 and 2 in byte
*byte |= (value << 1); // stores bits 0 and 1 into bits 2 and 3
}
void ClearC(unsigned char * byte) {
*byte &= 7; // squashes bits 3 to 7 to 0
}
void SetC(unsigned char * byte, unsigned char value) {
value &= 0x1F; // ensures only bits 0 to 4 can be set
*byte &= ~(0x1F << 3); // squashes correct bits in byte
*byte |= (value << 3); // or's in the bits at the right place
}
#else
extern void SetA(unsigned char *);
extern void SetB(unsigned char *, unsigned char);
extern void SetC(unsigned char *, unsigned char);
extern void ClearA(unsigned char *);
extern void ClearB(unsigned char *);
extern void ClearC(unsigned char *);
#endif
int main() {
volatile struct BF bf;
bf.a = 1;
bf.b = 2;
bf.c = 3;
SetA(&noBF);
SetB(&noBF, 2);
SetC(&noBF, 3);
printf("noBF should be 0x1D - value: 0x%X\n", (unsigned int) noBF);
printf("bf should be 0x1D - value: 0x%X\n", (unsigned int) *((unsigned char *) &bf));
return 0;
}