Menu

Variables in assembler

Help
5 days ago
1 day ago
  • Roger Jönsson

    Roger Jönsson - 5 days ago

    Slowly getting there. I am now getting correct results from the 8x8 Hardware Multiplier of the PIC 18F57Q84. -Great stuff!

    I hacked back and forth and finally made it work after sliding around for a good while, but I wonder why I can sometimes use variables to the get numbers in and in other cases not. Is it because GC-basic decides to not interfer as soon as it detects assembler?

    #Chip 18F57Q84, 64
    #Option Explicit
    #include <glcd.h>
    
    #DEFINE GLCD_TYPE         GLCD_TYPE_SSD1306_64x32 
    #DEFINE GLCD_I2C_Address  0x78 
    
    // Define I2C Software settings
      #DEFINE I2C_MODE Master
      #DEFINE I2C_DATA    PORTC.4
      #DEFINE I2C_CLOCK   PORTC.5
      #DEFINE I2C_DISABLE_INTERRUPTS ON
    
    
    dim aaa, bbb as byte
    dim ccc As Word Alias cccH, cccL
    dim num1 as byte
    
    aaa=21
    bbb=14
    
    //From Microchip data sheet ok (works with variables not with numbers):
    movf aaa , W
    mulwf bbb
    
    //Hardware Multiply ok (works with numbers not with variables)
    // MOVLW 20
    // MOVWF num1
    // MOVLW 14
    // MULWF num1
    
    //alt Hardware Multiply ok (works with numbers not with variables)
    // MOVLW 20
    // MULLW 14
    
    cccH=prodh 'prodh
    cccL=prodl 'prodL
    
    
    GLCDPrint (0, 0, aaa)
    GLCDPrint (0, 10, bbb)  
    GLCDPrint (0, 20, ccc)  
    
     
  • Anobium

    Anobium - 5 days ago

    I am not sure I get the issue.

    When using ASM the compile will pass whatever you write direct to the assembler. It has NO constrains and to be honest.. even I no longer use ASM. I trust GCBASIC compiler more and more.


    The compile will use hardware multiple for PIC, AVR and LGT when it can. There has to be a hardware multiplier and it has to be 'safe' calculation. Safe being byte calculations as these hardware instructions do not update status flags (e.g., Zero or Carry), unlike the GCBASIC arithmetic operations.

    GCBASIC writes very tight maths routines using the hardware when it can.

     
  • Roger Jönsson

    Roger Jönsson - 5 days ago

    It's not an issue. I just wondered why this behaviour and didn't understand it.

    If GCBASIC is already using the hardware multiplier, then I just wasted time. I searched and saw no mention about it, so I figured I it would be worth testing.
    It was late yesterday and I skipped measuring. I was thinking of doing it later, but there is no point if it is already used and then it is really great and now there is a thread about it, so the next fool is pointed in the right direction.

     
    • Anobium

      Anobium - 5 days ago

      🛠️ GCBASIC compiler behaviour

      PIC code generation

      This is the source for the compiler.

      'Use hardware multiply instruction for byte*byte multiply
      If CalcType = "BYTE" And Act = "*" And ChipFamily = 16 Then
        If IsConst(V1) Then
          CurrLine = LinkedListInsert(CurrLine, " movlw " + Str(MakeDec(V1)))
        Else
          CurrLine = LinkedListInsert(CurrLine, " movf " + V1 + ",W")
        End If
        If IsConst(V2) Then
          CurrLine = LinkedListInsert(CurrLine, " mullw " + Str(MakeDec(V2)))
        Else
          CurrLine = LinkedListInsert(CurrLine, " mulwf " + V2)
        End If
        AV = "PRODL"
      End If
      

      What the compiler is doing internally

      1. Load operand 1 into WREG
        Either via movlw (constant) or movf.

      2. Execute MULWF or MULLW
        This triggers the hardware multiplier.

      3. Assume the low byte of the result is in PRODL
        The compiler sets AV = "PRODL" because PIC stores the low byte there.

      4. Ignore flags
        Because the multiplier never sets them.

      5. Trust the user not to need PRODH unless explicitly requested
        Many compile languages only return an 8‑bit result for byte×byte.

      This is why PIC compilers must be careful: PRODL/PRODH are global, shared, and volatile.


      AVR/LGT code generation

      This is the source for the compiler.

      'Use hardware multiply instruction for byte*byte multiply
      If CalcType = "BYTE" And Act = "*" And ModeAVR And HMult Then
        CurrLine = LinkedListInsert(CurrLine, " mul SysByteTempA,SysByteTempB")
        AV = "SysByteTempX"
      End If
      

      What the compiler is doing internally

      1. AVR has a true ALU-integrated multiplier.
        The result always goes into:

      2. R0 = low byte

      3. R1 = high byte

      4. The compiler uses temporary registers (SysByteTempA/B) because AVR multiply destroys R0/R1.

      5. The compiler sets AV = "SysByteTempX" meaning:
        “The result is now in the temp register where we copied R0.”

      6. AVR flags are also not updated by MUL.
        Same reason: MUL is not part of the ALU flag path.


      🔍 Architectural comparison

      Feature PIC16/18 AVR/LGT
      Multiplier integrated with ALU? No Yes-ish (still separate but closer)
      Updates Zero/Carry? No No
      Result registers PRODL/PRODH R0/R1
      Side‑effects Global registers overwritten Global registers overwritten
      Compiler complexity High (banking, PRODL/PRODH) Moderate (R0/R1 save/restore)

      🧠 Why GCBASIC compiler treats PIC multipliers very carefully

      • PRODL/PRODH are global and not banked.
      • Interrupts can corrupt them.
      • Inline ASM can corrupt them.
      • Library routines may use them.
      • Flags are not updated, so conditional logic must be explicit.
      • Multi‑precision arithmetic must manually check PRODH.... hence this is not implemented

      This is why GCBASIC compilers wrap multiply operations in helper routines or generate defensive code.

       
  • Anobium

    Anobium - 5 days ago

    This reads like I am the smart one. I am not. I am looking at the code Hugh wrote when he was a youngling. He made the right decision from an architectual approach. Use the harware ONLY when safe and generated defensive/robust code.

    Thank you, Hugh.

     
  • Roger Jönsson

    Roger Jönsson - 5 days ago

    "5. Trust the user not to need PRODH unless explicitly requested"

    So should I mutliply as usual with GCbasic and then read from prodh directly to paste a word together. Is that what this says? I could really use the resulting word value.

     
    • Anobium

      Anobium - 5 days ago

      Just use normal maths. I would not underwrite any asumptions on the state of PRODH. You would have to disable interrupts, looks for errors and zero.

       
  • Roger Jönsson

    Roger Jönsson - 5 days ago

    The warnings are likely no problem in my case. I will be using inside one single interrupt. It will be for generating audio, so a failure will not exactly be life threateneing to most humans. Good to know though.

     
    • Anobium

      Anobium - 5 days ago

      Warnings! What warning? Memory warnings?

       
  • Roger Jönsson

    Roger Jönsson - 5 days ago

    I meant your list above.
    ...
    PRODL/PRODH are global and not banked.
    Interrupts can corrupt them.
    Inline ASM can corrupt them.
    ...
    etc

     
    • Anobium

      Anobium - 5 days ago

      If you have an interrupt.. do not use PRODH. My advice. Use GCBASIC regular maths.

       
  • Roger Jönsson

    Roger Jönsson - 5 days ago

    If I use it after the interrupt has triggered and before it triggers next time. What is it that may happen?

     
    • Anobium

      Anobium - 5 days ago

      As there is no way of knowing when the maths was interrupted the W will be corrupted ( this is sort of a guaranteed ).

       
  • Roger Jönsson

    Roger Jönsson - 5 days ago

    I find this is intriging. Sorry for being persistant.
    If I am doing the multiplication inside the only interrupt, immediately storing the result. What may interrupt/corrupt it?

     
  • Anobium

    Anobium - 5 days ago

    If I use it after the interrupt has triggered and before it triggers next time. What is it that may happen?

    You mean.
    If I use it within the interrupt handler . What is it that may happen?

    It should be ok.

     
  • Jerry Messina

    Jerry Messina - 1 day ago

    it might be worth noting that for the 18FxxQ84 the PRODx regs are saved as part of the hardware context

     

Log in to post a comment.

MongoDB Logo MongoDB