Keil Logo

Bitwise logical AND stores in a bit ....

Next Thread | Thread List | Previous Thread Start a Thread | Settings

Details Message
Read-Only
Author
Arnaud DELEULE
Posted
25-Feb-2002 17:14 GMT
Toolset
C51
New! 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

Read-Only
Author
Mike Kleshov
Posted
25-Feb-2002 18:14 GMT
Toolset
C51
New! RE: Bitwise logical AND stores in a bit ....
In the standard it is stated that a bit-field is interpreted as a signed or unsigned integer type consisting of the specified number of bits. In your case it's unsigned integer 1 bit wide. Conversion rules for unsigned integers imply that the compiler should take the LSB, which it did.
Regards,
Mike
Read-Only
Author
Arnaud DELEULE
Posted
26-Feb-2002 07:06 GMT
Toolset
C51
New! RE: Bitwise logical AND stores in a bit ....
Why not, but how do you explain a different casting rule when the destination is a "real bit"
void main (void)  {
  unsigned char  dummy = 0x55;
  bit   bitValue;

  bitValue = dummy & 0x40;

  return;
}
It results in :
MOV A,#0x55
MOV C, 0xE0.6
MOV 0x20.0, C
Now if destination is a bit, the cast considers that the result is the 6th bit (mask with 0x40).

Why different casting rules occurs for a similar destination format (1-bit wide) ?

Moreover, in the above "C" code, if the 0x40 mask is replaced by multibyte mask (like 0x44)
the result is 0 if no bit match the mask and 1 if there is at least one :
MOV A,#0x55
ANL A,#0x44
ADD A,#0xFF
MOV 0x20.0, C


This is very confusing....and should be checked each time ...

Cheers

Arnaud
Read-Only
Author
Andrew Neil
Posted
26-Feb-2002 09:46 GMT
Toolset
C51
New! RE: Bitwise logical AND stores in a bit ....
The bit type is a specific Keil extension, so they can implement it in the most efficient, target-specific way they can think of - without having to worry about any other ANSI constraints;
Bitfields, on the other hand, are standard ANSI - so Keil may well be constrained in their implementation (and implementations of bitfields are notorious for being inefficient!)

BTW: Have you disabled the defualt ANSI Integer Promotions?
Read-Only
Author
Arnaud DELEULE
Posted
26-Feb-2002 10:56 GMT
Toolset
C51
New! RE: Bitwise logical AND stores in a bit ....
> The bit type is a specific Keil extension,
> so they can implement it in the most efficient,
> target-specific way they can think of - without
> having to worry about any other ANSI constraints;

Why not, but it is not a reason to have opposite result when using
a bit type or a bit in bit-field type !!!

> Bitfields, on the other hand, are standard ANSI
> - so Keil may well be constrained in their
> implementation (and implementations of bitfields
> are notorious for being inefficient!)

My problem is not efficiency but COHERENCY of the compiled code !
If I used a bit-field type stored in BDATA, or a byte with sbit declarations, the result will be different !!!
So, if you write your code using Keil bit type, the result will be good, whereas using bit-field type (for portability), the result will be false !!!

Not really coherent ! ;-(

Is that a compiler bug or a normal issue ?

> BTW: Have you disabled the defualt ANSI Integer Promotions?
Obviously Yes, but no change.


Arnaud DELEULE



Read-Only
Author
Bob Horeck
Posted
26-Feb-2002 14:24 GMT
Toolset
C51
New! RE: Bitwise logical AND stores in a bit ....
The code in Araund's example is correct. The first example where C is set from E0.6 (actually Accumulator bit 6 .. E0 is the ACC sfr) is exactly the value specified.

In the second example, the and with 0x44 and add 0xff sets carry if either of the two bits in the mask are non-zero.

Looks to me like the compiler did exactly as it should.
Read-Only
Author
Arnaud DELEULE
Posted
26-Feb-2002 15:26 GMT
Toolset
C51
New! RE: Bitwise logical AND stores in a bit ....
You're right.
It does exactly what it should when the destination is a Keil "bit" type.
If the type of the destination is a 1-bit wide field in a bit-field structure,
the result will be different.

For me, that should not happen.

Regards

Arnaud
Read-Only
Author
Graham Cole
Posted
26-Feb-2002 09:52 GMT
Toolset
C51
New! RE: Bitwise logical AND stores in a bit ....
That bit of assembly code looks wrong. Should it not read:
...
ANL A,#0x40
...
It is, in my opinion, something of a failing of 'C' that in spite of having logical operators it does not offer a boolean type. I make it a habit to always use a logical operator when I want an boolean result. This removes any possibility of confusion and is something that the Keil compiler generally handles efficiently.

For example, I would write:
bitUnion.cCtrlStruct.bEnable = ( dummy & 0x40 ) != 0;
Read-Only
Author
Arnaud DELEULE
Posted
26-Feb-2002 11:02 GMT
Toolset
C51
New! RE: Bitwise logical AND stores in a bit ....
OK, good workaround !
I will try to make it a habit ! ;-)
It will avoid compiler-dependant result.

Arnaud DELEULE
Read-Only
Author
Norbert Paul
Posted
27-Feb-2002 12:29 GMT
Toolset
C51
New! RE: Bitwise logical AND stores in a bit ....
I recently invented this macro to access Bits in a Byte:

#define BITREF(aByte,aPos)((struct {unsigned char _0:1;unsigned char _1:1;unsigned char _2:1;unsigned char _3:1;unsigned char _4:1;unsigned char _5:1;unsigned char _6:1;unsigned char _7:1;}*)&aByte)->_##aPos

which even works as l-value with XDATA
(that's the reason, why I made it):

byte xdata b;
BITREF(b,4) = 1;
BITREF(b,7) = BITREF(b,4);

Arnaud DELEULE is right.

I looked up the specification of the bit data type.
The difference between variable of type bit and
a struct-member of size 1bit is not documented.
So to me it doesn't seem consistant too.

Norbert
Read-Only
Author
Mark Odell
Posted
27-Feb-2002 18:49 GMT
Toolset
C51
New! RE: Bitwise logical AND stores in a bit ....
Variables with leading underscores are reserved for use by the implentation. As are functions starting with 'str'. Be aware.

- Mark
Read-Only
Author
Norbert Paul
Posted
27-Feb-2002 19:22 GMT
Toolset
C51
New! RE: Bitwise logical AND stores in a bit ....
I'm aware.

These aren't really variables. I dont see any possibility
for an implementation to interfere with _mbr in:
struct {some_type_here _mbr;} variable;

It could be any prefix as well. I just wanted someprefix
for my little digits to lean on.

Norbert
Read-Only
Author
Mark Odell
Posted
27-Feb-2002 20:38 GMT
Toolset
C51
New! RE: Bitwise logical AND stores in a bit ....
If I write a compiler and have some internal _mbr variable used in one of my libraries it would be within my right. Then you'd have a problem. My point is, never use _ as a leading char in anything. It's just safer.

- Mark
Read-Only
Author
Jon Ward
Posted
27-Feb-2002 19:23 GMT
Toolset
C51
New! RE: Bitwise logical AND stores in a bit ....
You are not comparing apples to apples here.

In one case, you are assigning a value to a bit variable that is stored in the bit memory space. This is NOT a defined type in the ANSI C specification. As such, you can simply set or clear the bit without masking other adjacent bits.

In the other case, you are assigning a value to a bit field in a stucture. The bit field is a part of a char and so the changed value must be masked and logically ORed with the original byte. This generates more code.

Jon
Read-Only
Author
Arnaud DELEULE
Posted
28-Feb-2002 11:29 GMT
Toolset
C51
New! RE: Bitwise logical AND stores in a bit ....
I don't understand why a 1-bit variable will get a different result depending on its location mapping.
It's not a question of code size but only of result !

If you write
unsigned char   dummy = 0x55;
bit  bitValue;

void main (void)  {
    bitValue = dummy & 0x74;
    return;
}
The compiler will generate :
MOV A, dummy
ANL A,#0x74
ADD A, #0xFF
MOV bitValue, C
So the bitValue will contain 1, which is the expected result

If you use a bit-field structure, like in the following code :
typedef struct  {
    unsigned char  bEnable          : 1;
    unsigned char  cUnused          : 7;
} BitFieldStruct;

unsigned char   dummy = 0x55;
BitFieldStruct  bdata bitUnion;

void main (void)  {
    bitUnion.bEnable = dummy & 0x74;
    return;
}
The generated code is :
MOV A, dummy
ANL A,#0x00
MOV R7, A
MOV A, bitUnion
ANL A,#0xFE
ORL A, R7
MOV bitUnion, A

And the stored result will ever be 0 !!!

This inconsistency of the result is a big problem for me !

Thanks for all the reply which give me workaround.
But I think that I compare apple with apple because a 1-bit variable and a 1-bit in a bitfield varaible are quite equivalent in term of size.

Cheers.

Arnaud
Read-Only
Author
Norbert Paul
Posted
28-Feb-2002 13:21 GMT
Toolset
C51
New! RE: Bitwise logical AND stores in a bit ....
I guess, it can be understood like this:

bit and unsigned char:1 are DIFFERENT types:

bit can be seen similar to the bool type in C++: 0 is false, anything else is true.

Integers of 1 bit size are not boolean. Rather do they still remain integers restricted to the range {0,1}. They are "arithmetical", bits on the other hand are "logical".

A numerical value casted to bit therefore must yield 1 (i.e. true) if it would succeed as a proposition in a control statement, otherwise it must yield 0 (i.e. false).

A numerical value casted to an integer with less size (e.g 1) however must be stripped off the "excessive" bits in its binary representation, leaving possibly only the LSB. So these propositions hold:
(bit)2 == 1;      /*logical use */
(uchar:1)2 == 0; /* arithmetic use (this isn't C-Syntax, I know)*/
This explains the difference, but to me too this is an improper mix of types and memory locations, because if bit (if seen as synonym for bool) is a type it should be allowed to reside anywhere.

This:
bit xdata externalBit;  /*why not?*/
should be allowed.

Norbert
Read-Only
Author
Graham Cole
Posted
28-Feb-2002 14:13 GMT
Toolset
C51
New! RE: Bitwise logical AND stores in a bit ....
Arnaud, the compiler is generating correct code. You are casting from an 8-bit unsigned char to a 1-bit unsigned char. The rule when casting from a large unsigned type to a smaller unsigned type of variable is simply to discard the most significant bits. You will find that the same sort of thing happens when you cast from an unsigned int to an unsigned char – the 8 most significant bits of the unsigned int are discarded.

Norbert is quite correct to say that bit memory and and a 1-bit bit field are not the same thing. In C you have to be vary careful with Booleans – only logical operators and some functions return truly Boolean results.

However:
bit xdata externalBit;  /*why not?*/
cannot be allowed because bit is a memory type not a variable type. In fact, C51 does not allow variable stored in bit memory to have a type!

So, when you compile this:
typedef struct  {
    unsigned char  bEnable          : 1;
    unsigned char  cUnused          : 7;
} BitFieldStruct;

unsigned char   dummy = 0x55;
BitFieldStruct  bdata bitUnion;

void main (void)  {
    bitUnion.bEnable = dummy & 0x74;
    return;
}
You get this:
0000 900000      R     MOV     DPTR,#dummy
0003 E0                MOVX    A,@DPTR
0004 5400              ANL     A,#00H
0006 FF                MOV     R7,A
0007 E500        R     MOV     A,bitUnion
0009 54FE              ANL     A,#0FEH
000B 4F                ORL     A,R7
000C F500        R     MOV     bitUnion,A
000E         ?C0085:
000E 22                RET     
So, why is A anded with #00H and not 74H – that will be the compiler predicting that you are not interested in the 7 most significant bits. Note the effect of a small change to your code:
….
unsigned char   dummy = 0x55;
BitFieldStruct  bdata bitUnion;

void main (void)  {
    bitUnion.bEnable = dummy & 0x71;
    return;
}
Will give you this:
0000 900000      R     MOV     DPTR,#dummy
0003 E0                MOVX    A,@DPTR
0004 5401              ANL     A,#01H
0006 FF                MOV     R7,A
0007 E500        R     MOV     A,bitUnion
0009 54FE              ANL     A,#0FEH
000B 4F                ORL     A,R7
000C F500        R     MOV     bitUnion,A
000E         ?C0085:
000E 22                RET     
That is, bitUnion.bEnable is assigned the value of the least significant bit of dummy.

If that is not what you wanted, it is because you are not coding correctly. What you actually want is something like this:
typedef struct  {
    boolean          bEnable          : 1;
    unsigned char  cUnused          : 7;
} BitFieldStruct;

unsigned char   dummy = 0x55;
BitFieldStruct  bdata bitUnion;

void main (void)  {
    bitUnion.bEnable = ( dummy & 0x74 ) != 0;
    return;
}
Which generates this:
0000 900000      R     MOV     DPTR,#dummy
0003 E0                MOVX    A,@DPTR
0004 5474              ANL     A,#074H
0006 6004              JZ      ?C0085
0008 7F01              MOV     R7,#01H
000A 8002              SJMP    ?C0086
000C         ?C0085:
000C 7F00              MOV     R7,#00H
000E         ?C0086:
000E EF                MOV     A,R7
000F 5401              ANL     A,#01H
0011 FF                MOV     R7,A
0012 E500        R     MOV     A,bitUnion
0014 54FE              ANL     A,#0FEH
0016 4F                ORL     A,R7
0017 F500        R     MOV     bitUnion,A
0019         ?C0087:
0019 22                RET     
Which is the compiler's rather long-winded way of doing this:
0000 900000      R     MOV     DPTR,#dummy
0003 E0                MOVX    A,@DPTR
0004 5474              ANL     A,#074H
0006 6004              ADD	A,#FFH
0012 E500        R     MOV     A,bitUnion
0014 54FE              MOV	Acc.0,C
0017 F500        R     MOV     bitUnion,A
0019         ?C0087:
0019 22
Read-Only
Author
Arnaud DELEULE
Posted
28-Feb-2002 17:02 GMT
Toolset
C51
New! RE: Bitwise logical AND stores in a bit ....
OK, I understand the thought process
but I guess that very few people do 1-bit arithmetic.
But that the way Keil choose and it is one solution.
Not the way for me, but that's the life ! ;-)

Thanks all for your help and explanations

Arnaud
Read-Only
Author
Graham Cole
Posted
27-Feb-2002 14:44 GMT
Toolset
C51
New! RE: Bitwise logical AND stores in a bit ....
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]
Read-Only
Author
Jon Ward
Posted
28-Feb-2002 01:42 GMT
Toolset
C51
New! RE: Bitwise logical AND stores in a bit ....
The reason that sbit and sfr were chosen to work the way they do is because of historical reasons.

At the time the first C compiler for the 8051 was introduced, EVERYONE thought that a C compiler for the 8051 was a joke. The THEN-STANDARD was the Intel PL/M-51 compiler and the ASM51 assembler. If you do a little research, you'll figure out that the Keil Compiler and Assembler mimic many of the commands and keywords used by these Intel tools (that are no longer available). The reason for this was simple...make it easy for people to intermix the Intel and the Keil tools.

Eventually, Intel left the 8051 tools marketplace and they left with it a lot of technology that was invented in 1980-1982 -- 20 years ago. The 8051 has held up unbelievably well over the past 20 years. However, some of the original limitations are only now being addressed.

As an innovator in the 8051 marketplace Keil Software has 2 challenges. 1) Add new functionality and features that customers request and need. 2) Break as few existing applications as possible.

Keil is not the only tool vendor that most developers work with. There are board companies, emulator companies, code generation tools, device programmers, libraries, and so on. Radical changes to the structure of the C51 Programming Language and to the OMF51 Object File causes a ripple effect through the tools industry. And, it typically takes YEARS for other third-party tools vendors to accommodate.

Ergo, we avoid changing the product in radical ways that will negatively affect customers. I mean, it really sucks when we add a new feature that would help a particular customer only to find out that company XYZ has not integrated OMF changes from 3 years ago.

If I were KING of the embedded universe, there are a lot of things I would change about tools (in general) and about almost every 8-bit, 16-bit, and 32-bit architecture I've worked with. But, then, there would be no software development challenge and no interesting problems to solve.

Jon
Read-Only
Author
Graham Cole
Posted
28-Feb-2002 10:42 GMT
Toolset
C51
New! RE: Bitwise logical AND stores in a bit ....
Jon, thank you for your comments. My [rant] was just to get something off my chest – I didn't really expect a reply. I guessed that the reasons for sfr and sbit were historical and I don't seriously expect Keil to go making huge changes and certainly not any that would affect existing applications.

I am still left with a couple of gripes that I feel are legitimate and should be considered by Keil. I believe that these suggestions could be implemented without adversely affecting existing applications.

1-bit fields in structures are very common is my applications and I would think that would go for most other C51 applications too. Whatever failings the 80C51 may have, it is actually quite good at bit-twiddling and that can be a reason for choosing to use a processor from the family. Keil C51, however, does not seem to generate efficient code for 1-bit fields; C51 seems to generate much the same sort of code regardless of the number of the bits in a field. It would be a big help if the compiler/optimiser could treat 1-bit fields as a special case and use bit addressing instructions to accesses a copy of a variable held in, say, the Acc or B register. This would result in faster and more compact code. Also, it would encourage programmers to use bit fields rather than masks – the former being clearer and less error-prone.

bit defines a memory type, but C51 does not allow a type to be specified for a variable stored in bit memory. Of course, this does not actually stop me writing the software that I want, but if I move a Boolean variable between bit memory and any other memory type I have to add or remove a type definition. Variables that do not have a type make me feel uncomfortable – if I can assign a type to a 1-bit field, why can't I assign a type to a bit? If enumerated types with exactly two possible states could, optionally, be assigned to bit variables, then I could check for breaches of strong typing rules – and that is a software quality issue for me.

Finally, a compiler option could allow C51 automatically to assign enumerated types (with exactly two possible states) to bit memory when the memory model is small. This would make it quicker and easier to write small applications without having to worry about different types of memory model – an important consideration for Keil beginners. The resulting applications would be faster, more compact and more portable.

If you are still reading, thanks for your attention. I realise that all this is a lot easier to write about than to actually do! Keil C51 is an excellent compiler – I just love it so much that I want it to be perfect!
Read-Only
Author
Jon Ward
Posted
28-Feb-2002 16:11 GMT
Toolset
C51
New! RE: Bitwise logical AND stores in a bit ....
Graham,

Those are all good ideas. Bit variables, are unfortunately, and oddity of the 8051 (and C16x) architecture. They are only included in the compiler because SETB and CLR instructions are faster than the read-modify-write equivalents.

As for using the CLR and SETB instructions on bitfields, I'm not sure that this would actually improve the performance. If you consider that the unsigned char/int of the bitfield must be read and written back, that is 2 instructions. A set (LOGICAL OR) operation only requires 1 instruction to set up to 8 bits in a byte. And that would be faster than using several SETB instructions. For the case of setting a single bit, the code generated would be the same.

A clear operation (LOGICAL AND) is the same--only one instruction is required to clear 1-8 bits.

A clear and set operation (LOGICAL AND plus LOGICAL OR) requires 2 instructions, the AND mask and the OR mask--but only for multi-bit bitfields.

Anyway, we'll keep looking at this to see if we can improve code generation for these types of operations.

As for the bit typing, you can use the BDATA memory space to place typed variables in the bit-addressable area. But I'm not sure this is what you want.

Jon
Read-Only
Author
Graham Cole
Posted
1-Mar-2002 17:17 GMT
Toolset
C51
New! RE: Bitwise logical AND stores in a bit ....
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;
	}
}
This:
	r = s | t;
Gave me this
                                           ; SOURCE LINE # 25
0000 A200        R     MOV     C,t
0002 7200        R     ORL     C,s
0004 9200        R     MOV     r,C
 
But this:
	r = s || t;
Gave me this:
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
I was surprised because I expected that the logical operator would not only be the correct choice when a logical result was required, but also the most efficient. I always use the logical operator in my code where it is appropriate – so there is an opportunity for more compact code here.

This:
	byte.bit0 = TRUE;
Gave me this:
                                           ; SOURCE LINE # 28
0012 E500        R     MOV     A,byte
0014 4401              ORL     A,#01H
0016 F500        R     MOV     byte,A
That is a read-modify-write. Where the bit field is in data memory this could be reduced to ORL byte,#01H.

This:
	byte.bit1 = r;
Gave me this:
                                          ; 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
But the same could have been done with less than half as much code:
0018 A200        R     MOV     C,r
001A E500        R     MOV     A,byte
001C 54FD              MOV     Acc.1,C
001E F500        R     MOV     byte,A
This:
	if( byte.bit3 )
Gave me this:
                                           ; 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
But all that is needed is something like this:
006F E500        R     MOV     A,byte
0071 30E002            JNB     ACC.3,?C0007

Next Thread | Thread List | Previous Thread Start a Thread | Settings

  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.