Menu

Problems with comparisons with a Bitwise operator

Siddy
2019-08-10
2019-08-12
  • Siddy

    Siddy - 2019-08-10

    It's me again ;-). I read the "Read this first", and I'm using Great Cow BASIC (0.98.06 2019-06-12 (Windows 32 bit)). Running it on WINE under Ubuntu 18.04. (RIP Windows. Win7 was the last great Windows OS.)

    So I'm trying to do a bitwise mask to check if a particular bit in a register is high, as follows:

        if H_Byte & 0x10 = 0x10 Then ...
    

    And it never got called. I did debugging, which verified that "H_Byte" was indeed 0x90, which should work. (0x90 & 0x10 = 0x10.) I dug into the compiled source to find this:

    ;if H_Byte & 0x10 = 0x10 Then
        movf    H_BYTE,W
        movwf   SysTemp1
        btfss   SysTemp1,0
        goto    ENDIF7
    

    Umm...I don't see a bitwise AND operation, much less my 0x10.

    I also tried it without the "= 0x10" check, with the following result:

    ;if H_Byte & 0x10 Then
        movlw   16
        andwf   H_BYTE,W
        movwf   SysTemp1
        btfss   SysTemp1,0
        goto    ENDIF7
    

    This of course is assuming that "FALSE = 0" and anything else is "TRUE", which may not be the case with the GCB design. Regardless the result of the bitwise AND mask will be either 0x00 or 0x10--neither of which will get caught by the BTFSS (which in this case will only determine if the result is even or odd.)

    I need to get my project working, so I'll just use an individual bit check, as follows:

    ;if H_Byte.4 Then
        btfss   H_BYTE,4
        goto    ENDIF7
    

    Just thought I'd let the dev team know of this.

     

    Last edit: Siddy 2019-08-10
    • Anobium

      Anobium - 2019-08-11

      Thanks for the great post. I thought we had resolved this type of issue,

      Your workaround is good but you try this... the compiler gets a little hand with this code.

      if ( H_Byte and 0x10 ) = 0x10 Then
      
       
      • Siddy

        Siddy - 2019-08-11

        Aha, that makes sense. I suppose that means that the compiler is viewing it as
        if H_Byte and (0x10 = 0x10) Then
        and concluding that the last part is of no value. Regardless, checking the low bit for true/false seems to be the GCB "architecture" style (all routines based around that), so that'll just take some slightly different thinking (on my part).

        My code is working with the bit check, but if I ever have to check the result of an AND mask, I'll have to remember to put parentheses around it.

        Thanks.

         

        Last edit: Siddy 2019-08-11
        • Anobium

          Anobium - 2019-08-12

          Your summary is correct.

          I have put this on the issue list as we should try to resolve.

          Thank you.

           
  • Anobium

    Anobium - 2019-08-12

    Your summary is correct.

    I have put this on the issue list as we should try to resolve.

    Thank you.

    I have spoken with Hugh. I was incorrect. :-) I will let Hugh explain. :-)

     
  • Hugh Considine

    Hugh Considine - 2019-08-12

    All is well here, but this can be confusing at times and I've been bitten by this as well.

    In the order of operations, comparison operations have a higher precedence than boolean operations. GCBASIC behaves the same way as most other languages. We have to do this so lines like this (randomly taken from glcd_ili9326.h) work:

    if GLCDfntDefaultSize = 2 and CurrCharRow = 7 then
    

    Unfortunately, it is an easy mistake to make, I remembermaking this exact mistake in some VB.NET code years ago and lost a few hours trying to work out what I'd done.

    If you can use an individual bit check, that's generally the best way to go. These are a lot simpler for the compiler to deal with and result in much nicer assembly.

     
    • Siddy

      Siddy - 2019-08-12

      Now I get it.

      I suppose I was expecting the following ASM result, as I would have written it:

      ;if H_Byte & 0x10 Then
          movlw   16
          andwf   H_BYTE,W
          btfsc   STATUS,Z
          goto    ENDIF7   'result was zero
          'result was nonzero
      

      ...but that's not in line with the GCB architecture, which has to handle 32-bit variables, etc.

      Never mind, it's GCB--I could write in ASM right there like that if I wanted ;-). Thanks again.

       

Log in to post a comment.