#958 Incorrect boolean logic for expressions


Here is a code snippet from the assembler output,
originating from the TUSB3210 keyboard sample code.

The C statement is interpreted incorrect / unexpected.
The two bit flags are not combined to an integer and the
parentheses are ignored.

The variables are defined as follows:
xdata at 0xFFFE unsigned char bUSBSTA;
#define USBSTA_STPOW 0x01 // comment 1
#define USBSTA_SETUP 0x04 // comment 2

;usb.c:736: if(bUSBSTA & (USBSTA_SETUP |
USBSTA_STPOW) != 0x00)
; genAssign
mov dptr,#_bUSBSTA
movx a,@dptr
; genAnd
; Peephole 105 removed redundant mov
mov r4,a
; genIfxJump
; Peephole 111 removed ljmp by
inverse jump logic
jnb acc.0,00109$

And as you can see, the code tests only the last of the
two flags. But the ored flags (0x05) should of course be
tested against bUSBSTA.
Rewriting the source by stripping the != 0x00 gives a
usable output :

;usb.c:736: if(bUSBSTA & (USBSTA_SETUP |


  • Erik Petrich

    Erik Petrich - 2005-07-27
    • milestone: 100454 --> non_bugs
    • status: open --> closed-rejected
  • Erik Petrich

    Erik Petrich - 2005-07-27

    Logged In: YES

    Either the sample code is in error or you missed a set of
    parenthesis when typing it in, since the compiler is
    operating correctly for your sample. The intended statement
    is probably:

    if ((bUSBSTA & (USBSTA_SETUP | USBSTA_STPOW)) != 0x00)

    Consulting a C reference book, I find that the != operator
    has higher precedence than the & operator. Thus
    (USBSTA_SETUP | USBSTA_STPOW) != 0x00 is evaluated first.
    Since 0x05 != 0x00 is true, the result of this subexpression
    is 1, which is what the compiler used for the second operand
    to the bitwise-AND operator.


Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

JavaScript is required for this form.

No, thanks