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

accessing local "c" variables in inline assembly

How do I access a local variable in assembly?

I have used the SRC to determine how the compiler created the variable. it changes it's name from variable to variable?nnn where nnn is a number.

How do I determine what nnn is? (other than looking at the .src file)
can I access the variable using the original label name?

If I use the variable:nnn , nnn will occasionally change and ten I get errors!

Help

  • How do I access a local variable in assembly?

    Only slightly simplified answer: you don't. Inline assembly in C51 isn't integrated anywhere near well enough with the C compiler to allow such tricks.

    Generally, the best idea is to re-evaluate the whole plan: are you absolutely sure that you need inline assembly for the task at hand?

  • You could either pass the local as a parameter to an assembler routine, or move up and write more of the calling code in assembler.

    With C51, you generally mix C and assembler function-by-function, not line-by-line inside a single function.

  • Try writing a dummy C subroutine passing the variable to it as an argument & returning it unchanged. Check the compiled assembly code & add any instructions to the code between the subroutines entry point & it's return of the value.

    Don

  • thanks,
    I have taken the C portion and replaced it with Assembler making the whole module assembler.

    re-evaluated why I was doing it seperately.

    MT

  • here is a Sample:

    void ProcessSerialSwitch()
    {
            data unsigned char i;
            data unsigned char RcvFIFOEmptyFlagLo;
            data unsigned char RcvFIFOEmptyFlagHi;
    //      char code Mask[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
    
    /*      MemSwitchReg();
            RcvFIFOEmptyFlagLo=XBYTE[RegAddrReceiveFIFOEmpty];
            RcvFIFOEmptyFlagHi=XBYTE[RegAddrReceiveFIFOEmpty+1];
            MemSwitchRam();
    */
    RcvFIFOEmptyFlagLo=0xFF;
    RcvFIFOEmptyFlagHi=0xFF;
    
            //对RcvFIFOEmptyFlagLo,RcvFIFOEmptyFlagHiæ¯ä¸€bit进行检测,若为1,则对åº"䏲壿œ‰æ•°æ®
            //ç"±äºŽCè¯­è¨€å¯¹ä½æ"作效率低,ä¸"此函数ç»å¸¸è¢«è°ƒç"¨ï¼Œæ"¹ä¸ºæ±‡ç¼–
            //for (i=0;i<SerialCount;i++) {
            //      if (i<8) {if (RcvFIFOEmptyFlagLo&Mask[i]) SerialSwitchReadChar(i);}
            //              else if (RcvFIFOEmptyFlagHi&Mask[i-8]) SerialSwitchReadChar(i);
            //}
    
    
            ACC=RcvFIFOEmptyFlagLo;
    
    #pragma asm
    
            checklo:
                    //MOV      A,RcvFIFOEmptyFlagLo
                    JZ      checkhi
    
    //              CLR      A
    #pragma endasm
                    i=0;
    #pragma asm
    
    //              MOV      i,A
    
            testlo:
    #pragma endasm
            ACC=RcvFIFOEmptyFlagLo;
    #pragma asm
    //              MOV      A,RcvFIFOEmptyFlagLo
                    JZ       checkhi
            lblrorlo:
                    CLR      C
                    RRC      A
                    JC               doreceivelo
                    JZ       checkhi
    //              INC              i
    #pragma endasm
                    i++;
    #pragma asm
                    JMP              lblrorlo
    
            doreceivelo:
            //      MOV              RcvFIFOEmptyFlagLo, A
    #pragma endasm
            RcvFIFOEmptyFlagLo=ACC;
            SerialSwitchReadChar(i);  //è¯»å–æ•°æ®
            i++;
            ACC=RcvFIFOEmptyFlagLo;
    #pragma asm
                    //inc      i
                    //MOV      A, RcvFIFOEmptyFlagLo
                    JNZ      lblrorlo
    
            checkhi:
    
    #pragma endasm
                    i=8;
                    ACC=RcvFIFOEmptyFlagHi;
    #pragma asm
    //              MOV      i,8
    //      testhi:
                    //MOV      A, RcvFIFOEmptyFlagHi
                    JZ       returnintr
    
            lblrorhi:
                    CLR      C
                    RRC      A
                    JC       doreceivehi
                    JZ       returnintr
    #pragma endasm
                    i++;
    #pragma asm
                    //INC      i
                    JMP      lblrorhi
            doreceivehi:
    //              MOV              RcvFIFOEmptyFlagHi, A
    #pragma endasm
            RcvFIFOEmptyFlagHi=ACC;
            SerialSwitchReadChar(i);
            i++;
            ACC=RcvFIFOEmptyFlagHi;
    #pragma asm
                    //inc      i
            //      MOV      A,RcvFIFOEmptyFlagHi
                    JNZ      lblrorhi
    
            returnintr:
                    RET
    
    
    #pragma endasm
    
    }
    
    

  • Forgive my ignorance here, but wouldn't it be ever so much easier to do all that with a little assembly language function?

  • Ignorance of all the OP's carefully-considered reasons that made it not ever so much easier to do all that with a little assembly language function in his particular application...

    Surely, he must have had plenty...

    ;-)

  • a Sample:

    This sample only proves that if you absolutely insist, you can drive a 10-inch nail into concrete using a fine-tip soldering iron, even if you have a perfectly usable hammer at hand.

    It spectacularly fails to answer the actual question, though: why the heck would anyone want to do such a thing?

  • this little snippet

    #pragma endasm
                    i=8;
                    ACC=RcvFIFOEmptyFlagHi;
    #pragma asm
    

    access the accumulator in C and, while it MAY not blow it all up, the practice is, at least, dangerous. Thus it does not matter if you can "access local "c" variables in inline assembly" since the whole mess, most likely, will blow up anyhow.

    To the OP
    rewrite the mess totally in assembler and look up the OVERLAYABLE command to the assembler, that will give you local variables in an assembler routine.

    Erik