Hi, I get a curious result when compiling such a following code :
typedef union { unsigned char cCtrlFullByte; struct { unsigned char bEnable : 1; unsigned char cUnused : 7; } cCtrlStruct; } CtrlUnion; void main (void) { unsigned char dummy = 0x55; CtrlUnion xdata bitUnion; bitUnion.cCtrlStruct.bEnable = dummy & 0x40; return; }
MOV A,#0x55 ANL A,#0x00 MOV R7,A MOV DPTR, #0x0000 MOVX A,@DPTR ANL A,#0xFE ORL A,R7 MOVX @DPTR, A
Jon, thanks for your comments. My apologies to Arnaud for high jacking his thread. At the risk of becoming tedious, I decided to do some experiments which have concluded with the following item of test code. The experiment has convinced me that bit fields are not accessed efficiently. I have been able to go and look at our latest application, it is about 60K bytes long and contains a number of modules doing a wide variety of things and written by a number of different programmers. I searched for the simple case of testing a 1-bit bit field in a simple if statement, I found just under 500 instances. An average saving of just 3 instructions in each case would give a code reduction of 2.5% which I think is significant. There are in the 60K application, at least as many logical operations as arithmetic operations – quite possibly more. Many of them involve 1-bit bit fields. Many things in the same application are achieved by means of masks whereas using bit fields would be more elegant, but currently will generate slower code.
typedef enum { FALSE, TRUE } boolean; typedef struct { boolean bit0 : 1; boolean bit1 : 1; boolean bit2 : 1; boolean bit3 : 1; boolean bit4 : 1; boolean bit5 : 1; boolean bit6 : 1; boolean bit7 : 1; } bit_field_type; extern bit do_stuff(); main( void ) { bit /*boolean*/ r, s, t; data boolean x; bit_field_type byte; r = s | t; r = s || t; byte.bit0 = TRUE; byte.bit1 = r; s = byte.bit2; byte.bit2 = s | !t; byte.bit7 = byte.bit5 && byte.bit6; if( byte.bit3 ) { r = TRUE; } }
r = s | t;
; SOURCE LINE # 25 0000 A200 R MOV C,t 0002 7200 R ORL C,s 0004 9200 R MOV r,C
r = s || t;
0006 200003 R JB s,?C0003 0009 300003 R JNB t,?C0001 000C ?C0003: 000C D3 SETB C 000D 8001 SJMP ?C0002 000F ?C0001: 000F C3 CLR C 0010 ?C0002: 0010 9200 R MOV r,C
byte.bit0 = TRUE;
; SOURCE LINE # 28 0012 E500 R MOV A,byte 0014 4401 ORL A,#01H 0016 F500 R MOV byte,A
byte.bit1 = r;
; SOURCE LINE # 29 0018 A200 R MOV C,r 001A E4 CLR A 001B 33 RLC A 001C 5401 ANL A,#01H 001E FF MOV R7,A 001F 25E0 ADD A,ACC 0021 FF MOV R7,A 0022 E500 R MOV A,byte 0024 54FD ANL A,#0FDH 0026 4F ORL A,R7 0027 F500 R MOV byte,A
0018 A200 R MOV C,r 001A E500 R MOV A,byte 001C 54FD MOV Acc.1,C 001E F500 R MOV byte,A
if( byte.bit3 )
; SOURCE LINE # 36 006F FF MOV R7,A 0070 13 RRC A 0071 13 RRC A 0072 13 RRC A 0073 541F ANL A,#01FH 0075 30E002 JNB ACC.0,?C0007
006F E500 R MOV A,byte 0071 30E002 JNB ACC.3,?C0007