This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Bitwise logical AND stores in a bit ....

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;
}


It results in :
MOV A,#0x55
ANL A,#0x00
MOV R7,A
MOV DPTR, #0x0000
MOVX A,@DPTR
ANL A,#0xFE
ORL A,R7
MOVX @DPTR, A 

I thought that the bit result of bitwise logical AND is 1 if result is not 0, else 0.
It seems that I didn't understand ANSI the same way than Keil compiler ? Am I wrong ?

Arnaud DELEULE

Parents
  • C51 does not currently generate efficient code accesses to 1-bit fields – it is as if C51 treats all bit fields the same way, no special case is made when the field size is 1-bit. That is a pity because 1-bit fields are very common in real-time programming and handling them more efficiently would be a significant benefit. Perhaps Keil can fix this for us?

    [rant]
    Why did Keil implement bit-size variables the way that they did? Currently, Keil C51 programs have to include this sort of thing:

    sbit 	return_path_signalling_pin	=	P1^0;
    sbit	line_fault_relay_pin		=	P1^1;
    sbit	control_output_pin		=	P1^2;
    sbit	control_output_plugin_pin	=	P1^4;
    sbit	line_fail_plug_in_pin		=	P1^5;
    sbit	comms_fail_plug_in_pin		=	P1^6; 
    
    This is very non-standard C – it requires the sfr and sbit keywords and the confusing re-use of the ^ operator. Yuk!

    Would it be possible for the compiler to allow the user to define enumerated types which the compiler would recognise as having only two possible states. For example a user defined boolean can only be FALSE or TRUE.

    In the case of bit fields, it should be possible to fit a 1-bit variable into a field of 1-bit.

    So, it should be possible to define any structure the user cares to. Bit field structures can then be used to define the structure of bit-addressable SFRs or to define a structure stored in bdata and the individual 1-bit fields will be accessed using bit-addresses. Bit field structures can also be used to defined the structure of non-bit-addressable SFRs and variables not in bdata, they cannot be bit-addressed, but they should otherwise function in exactly the same way.

    1-bit variables could be allocated to bits in bit addressable SFRs using the _at_ keyword. Entire SFRs can be described by using a structure with bit fields. So, we might hope for a syntax that resembles the following.
    typedef enum ( FALSE, TRUE ) boolean;
    …
    bit	boolean		carry 		_at_ 0xD7;
    bit	boolean		aux_carry 	_at_ 0xD6;
    bit	boolean		f0 		_at_ 0xD5;
    bit	boolean		overflow 	_at_ 0xD2;
    bit	boolean		f1 		_at_ 0xD1;
    bit	boolean		parity 		_at_ 0xD0;
    
    typedef struct {
    	boolean		carry		: 1;
    	boolean		aux_carry	: 1;
    	boolean		f0		: 1;
    	unsigned char	register_bank	: 2;
    	boolean		overflow	: 1;
    	boolean		f1		: 1;
    	boolean		parity		: 1;
    } psw_type
    
    data psw_type PSW _at_ 0xD0;
    
    …
    
    {
    	PSW.f0 = 0;				// bit addressable.
    	PCON.gf0 = 1;				// not bit addressable.
    …
    
    
    OK, so the sfr and sbit keywords are a pet hate of mine and it is quite possible that I have not made my meaning clear. However, this sort of thing requires less deviation from ANSI C and is, I think, less confusing; it would make bit size variables and 1-bit fields exactly the same and would probably prompt the compiler writers to implement efficient handling of 1-bit fields.
    [/rant]

Reply
  • C51 does not currently generate efficient code accesses to 1-bit fields – it is as if C51 treats all bit fields the same way, no special case is made when the field size is 1-bit. That is a pity because 1-bit fields are very common in real-time programming and handling them more efficiently would be a significant benefit. Perhaps Keil can fix this for us?

    [rant]
    Why did Keil implement bit-size variables the way that they did? Currently, Keil C51 programs have to include this sort of thing:

    sbit 	return_path_signalling_pin	=	P1^0;
    sbit	line_fault_relay_pin		=	P1^1;
    sbit	control_output_pin		=	P1^2;
    sbit	control_output_plugin_pin	=	P1^4;
    sbit	line_fail_plug_in_pin		=	P1^5;
    sbit	comms_fail_plug_in_pin		=	P1^6; 
    
    This is very non-standard C – it requires the sfr and sbit keywords and the confusing re-use of the ^ operator. Yuk!

    Would it be possible for the compiler to allow the user to define enumerated types which the compiler would recognise as having only two possible states. For example a user defined boolean can only be FALSE or TRUE.

    In the case of bit fields, it should be possible to fit a 1-bit variable into a field of 1-bit.

    So, it should be possible to define any structure the user cares to. Bit field structures can then be used to define the structure of bit-addressable SFRs or to define a structure stored in bdata and the individual 1-bit fields will be accessed using bit-addresses. Bit field structures can also be used to defined the structure of non-bit-addressable SFRs and variables not in bdata, they cannot be bit-addressed, but they should otherwise function in exactly the same way.

    1-bit variables could be allocated to bits in bit addressable SFRs using the _at_ keyword. Entire SFRs can be described by using a structure with bit fields. So, we might hope for a syntax that resembles the following.
    typedef enum ( FALSE, TRUE ) boolean;
    …
    bit	boolean		carry 		_at_ 0xD7;
    bit	boolean		aux_carry 	_at_ 0xD6;
    bit	boolean		f0 		_at_ 0xD5;
    bit	boolean		overflow 	_at_ 0xD2;
    bit	boolean		f1 		_at_ 0xD1;
    bit	boolean		parity 		_at_ 0xD0;
    
    typedef struct {
    	boolean		carry		: 1;
    	boolean		aux_carry	: 1;
    	boolean		f0		: 1;
    	unsigned char	register_bank	: 2;
    	boolean		overflow	: 1;
    	boolean		f1		: 1;
    	boolean		parity		: 1;
    } psw_type
    
    data psw_type PSW _at_ 0xD0;
    
    …
    
    {
    	PSW.f0 = 0;				// bit addressable.
    	PCON.gf0 = 1;				// not bit addressable.
    …
    
    
    OK, so the sfr and sbit keywords are a pet hate of mine and it is quite possible that I have not made my meaning clear. However, this sort of thing requires less deviation from ANSI C and is, I think, less confusing; it would make bit size variables and 1-bit fields exactly the same and would probably prompt the compiler writers to implement efficient handling of 1-bit fields.
    [/rant]

Children