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

Can I embed hard-coded bytes into program?

I want to write a macro which pushes IE onto stack and pops it out soon. How can I do it?
How to embed the code
0xc0, 0xa8 PUSH IE
and
0xd0, 0xa8 POP IE
into c program?

Parents
  • In my program there are some places need to save the IE first and disable EA, then do something, after that resume EA to the original state. So define a pair of macros to save IE into stack and restore it seems like a better idea. 
    
    I know the SRC and ASM/ENDASM, but it is an error to define the macro as these:
    
    #define SAVEIE()     #pragma ASM         PUSH IE         CLR  EA     #pragma ENDASM
    
    #define LOADIE()     #pragma ASM         POP  IE         CLR  EA     #pragma ENDASM
    
    

Reply
  • In my program there are some places need to save the IE first and disable EA, then do something, after that resume EA to the original state. So define a pair of macros to save IE into stack and restore it seems like a better idea. 
    
    I know the SRC and ASM/ENDASM, but it is an error to define the macro as these:
    
    #define SAVEIE()     #pragma ASM         PUSH IE         CLR  EA     #pragma ENDASM
    
    #define LOADIE()     #pragma ASM         POP  IE         CLR  EA     #pragma ENDASM
    
    

Children
  • Pushing EA onto the stack is the natural way for an assembly language programmer to work. I'm not sure that the macros that you suggest will work. I'm not clear why LOADIE includes a "CLR EA" instruction.

    In any event, including a #ASM in a module will require that the optimisation level is turned down to zero - for the whole module. That is not very desirable.

    You could try implementing a save_ie()and load_ie() functions in a different (separately compiled) module. They would look something like this:

    save_ie()
    {
    #pragma AMS
        POP  Acc
        POP  B
        PUSH IE
        PUSH B
        PUSH Acc
    #pragma ENDASM
    }
    
    load_ie()
    {
    #pragma AMS
        POP  Acc
        POP  B
        POP  IE
        PUSH B
        PUSH Acc
    #pragma ENDASM
    }
    
    main
    {
        save_ie();
        AE = 0;
        ..do stuff...
        load_ie();
    }
    
    Note how it is necessary to pop off the return address and then push it back on again. This will be just a little lower than in-line code.

    If you use global register optimisation (generally a good idea), you can include a $REGUSE directive in the assembly language to help the compiler produce optimum results - see assembler manual. Without REGUSE, compiler may be reluctant to assign automatic variables to registers in functions that call save_ie() and load_ie().

    Good luck.

  • Sigh...

    Use #pragma disable. For example:

    #pragma disable
    void interrupt_protected_function (void)
    {
    }
    

    #pragma disable saves then clears the EA bit on entry to the function and restores the EA bit on exit.

    If you use this you won't have to do wacky stuff like in-line assembly or weird macros.

    Jon

  • Maybe this will work:

    #define SAVEIE() { bit ie=IE; IE=0;
    #define LOADIE() IE=ie; }
    
    - Mike