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

Passing Variables between Assembly & C functions

Hi All,

I'm more of a Assembly guy than C.

I came across this forum when I am seeking for some quick guide of sharing data registers / variables of different files of C and .a51 in a simple program.

Calling each other from C to get the function written in .a51 or vice-versa is completed. Went through c2asm2c.zip, tested and find that it worked perfectly. However, I encounter some trouble when I need to pass on some variables that need to be manipulated from .a51 to .c

My case:-

Main code is in .a51. Requires to call a function that adds 20 slightly different 8bit data bytes and then take its average (i.e. by division).

Writing the function above in .a51 is a pain due to unavailable 16bit-addition in 8051 done under Keil uV2.

My solution thought:- is to write the addition function in C so addition can be done much more easily.

Problem:- how do I pass the variables/registers defined in .a51 to the C function to be called from .a51 environment? The C function failed to recognize the similar declared register under .a51 before. Do I need to declare them under a new name OR use the similar name of data registers OR can use some global declaration of data registers. But how?

Appreciate some really cool advice if available.

Cheers,
James

Parents
  • continuing...

    C source file:

    #include <test_h.H>   // include SFR and other definitions/macros
    
    // tell the linker known symbol names:
    
    // data DECLARED here (no memory space assigned here)
    // external data variables
    extern unsigned char data Char_dataA;
    extern unsigned char data Char_dataB;
    extern unsigned char data DataGroup1;
    extern unsigned char data DataGroup2;
    
    extern unsigned int data Int_data;
                                                    // not necessary:
    extern unsigned char data Int_dataH;            // MSB component of Int_data if you need it
    extern unsigned char data Int_dataL;            // LSB (Big Endian manner)
    
    extern unsigned long data Long_data;
                                                    // not necessary:
    extern unsigned char data Long_data1;           // MSB...
    extern unsigned char data Long_data2;           // t   components of Long_data
    extern unsigned char data Long_data3;           // o   if you need it
    extern unsigned char data Long_data4;           // ...LSB
    
    extern unsigned char data Char_array[A_LENGTH]; // defined in asm file
    
    // external bit variables
    extern bit Flag0;
    extern bit Flag1;
    extern bit abc;
    extern bit Flag7;
    extern bit Bit_var1;
    extern bit Bit_var2;
    
    // external bdata variables
    extern unsigned char bdata Flags1;
    extern unsigned char bdata Flags2;
    
    //Note:
    // sbit xyz = Flags1^3;       // names for particular bits of EXTERNAL
                                  // bdata variables CAN'T be defined this way,
    
    unsigned char bdata Flags3;   // but if the variable is DEFINED here,
    
    sbit xyz = Flags3^5;          // then names for particular bits of such
    sbit MNO = Flags3^7;          // bdata variables CAN be defined this way
    
    // external idata variables
    extern unsigned char idata Char_idata;
    
    // external xdata variables
    extern unsigned char xdata Char_xdata;
    
    // external functions
    extern void my_function_A51(void);
    extern void my_regpar_function_A51(unsigned char x);
    
    
    // global data DEFINED here (memory space assigned here)
    unsigned char data Divider;     // data type either explicitly (data)
    unsigned int abcd;              // or given by memory model
    unsigned char xdata Result;     // Result explicitly in xdata memory
    
    bit bit_var1_C;                   // bit variables defined in a C file
    bit bit_var2_C;
    
    unsigned char data data_var1_C;   // data variables defined in a C file
    unsigned char data data_var2_C;
    unsigned char idata idata_var_C;  // idata variables defined in a C file
    unsigned char xdata xdata_var_C;  // xdata variables defined in a C file
    
    void func_C(void)
    {
      // empty here
    }
    
    #pragma REGPARMS    // it is default
    void func_regpar_C(unsigned int y)  // function with parameters
    {
      DPTR = y; // use parameter(s)
    }
    
    void main(void)       // an example, mostly MEANINGLESS !!
    {
      unsigned char a, i; // local data (data type given by memory model used)
    
      if (Flag0) {
        a = Int_dataL + Long_data2;
      }
      else {
        a = Char_array[3];
      }
    
      Int_data = 0;
      for (i = 0; i < A_LENGTH; i++) {
        Int_data += Char_array[i];
      }
      Int_data /= A_LENGTH;
    
      // ...sum of 'chars' divided by their number gives 'char' again (=average)
      Result = Int_data;    // casting, better explicitly: (unsigned char)Int_data
    
      my_function_A51();                  // call external function without parameters
      my_regpar_function_A51(Char_idata); // call external function with parameter(s)
    
      while(1); // stop here forever
    }
    

    and "Test_h.H" header file:
    // put SFR and other definitions here (examples here)
    sfr ACC = 0xE0;                 // accumulator SFR address
    sfr PSW = 0xD0;                 // Program Status Register SFR address
    
    sbit ACC3 = ACC^3;              // bit ACC.0 in assembler
    sbit CY = PSW^7;                // bit Carry Flag - 7th bit of bitaddressable register PSW
                                    // bitaddressable SFRs have address' lower nibble 0 or 8
    
    sfr TL2 = 0xCC;                 // if LSByte address of a 16-bit SFR register (here Timer2)
    sfr TH2 = 0xCD;                 // is by 1 lower than its MSByte address,
    sfr16 TIMER2 = 0xCC; // =TL2    // then sfr16 can be defined for such an SFR register
                                    // and compiler will arrange everything else
    
    sfr DPL = 0x82;
    sfr DPH = 0x83;
    sfr16 DPTR = 0x82;
                                    // miscellaneous constants or preprocessor macro definitions:
    #define A_LENGTH        5       // size of the array "Char_array"
    

    I am sorry if it is too long.
    Copy and study it. Hope it helps you.

    Best wishes!
    Eric

Reply
  • continuing...

    C source file:

    #include <test_h.H>   // include SFR and other definitions/macros
    
    // tell the linker known symbol names:
    
    // data DECLARED here (no memory space assigned here)
    // external data variables
    extern unsigned char data Char_dataA;
    extern unsigned char data Char_dataB;
    extern unsigned char data DataGroup1;
    extern unsigned char data DataGroup2;
    
    extern unsigned int data Int_data;
                                                    // not necessary:
    extern unsigned char data Int_dataH;            // MSB component of Int_data if you need it
    extern unsigned char data Int_dataL;            // LSB (Big Endian manner)
    
    extern unsigned long data Long_data;
                                                    // not necessary:
    extern unsigned char data Long_data1;           // MSB...
    extern unsigned char data Long_data2;           // t   components of Long_data
    extern unsigned char data Long_data3;           // o   if you need it
    extern unsigned char data Long_data4;           // ...LSB
    
    extern unsigned char data Char_array[A_LENGTH]; // defined in asm file
    
    // external bit variables
    extern bit Flag0;
    extern bit Flag1;
    extern bit abc;
    extern bit Flag7;
    extern bit Bit_var1;
    extern bit Bit_var2;
    
    // external bdata variables
    extern unsigned char bdata Flags1;
    extern unsigned char bdata Flags2;
    
    //Note:
    // sbit xyz = Flags1^3;       // names for particular bits of EXTERNAL
                                  // bdata variables CAN'T be defined this way,
    
    unsigned char bdata Flags3;   // but if the variable is DEFINED here,
    
    sbit xyz = Flags3^5;          // then names for particular bits of such
    sbit MNO = Flags3^7;          // bdata variables CAN be defined this way
    
    // external idata variables
    extern unsigned char idata Char_idata;
    
    // external xdata variables
    extern unsigned char xdata Char_xdata;
    
    // external functions
    extern void my_function_A51(void);
    extern void my_regpar_function_A51(unsigned char x);
    
    
    // global data DEFINED here (memory space assigned here)
    unsigned char data Divider;     // data type either explicitly (data)
    unsigned int abcd;              // or given by memory model
    unsigned char xdata Result;     // Result explicitly in xdata memory
    
    bit bit_var1_C;                   // bit variables defined in a C file
    bit bit_var2_C;
    
    unsigned char data data_var1_C;   // data variables defined in a C file
    unsigned char data data_var2_C;
    unsigned char idata idata_var_C;  // idata variables defined in a C file
    unsigned char xdata xdata_var_C;  // xdata variables defined in a C file
    
    void func_C(void)
    {
      // empty here
    }
    
    #pragma REGPARMS    // it is default
    void func_regpar_C(unsigned int y)  // function with parameters
    {
      DPTR = y; // use parameter(s)
    }
    
    void main(void)       // an example, mostly MEANINGLESS !!
    {
      unsigned char a, i; // local data (data type given by memory model used)
    
      if (Flag0) {
        a = Int_dataL + Long_data2;
      }
      else {
        a = Char_array[3];
      }
    
      Int_data = 0;
      for (i = 0; i < A_LENGTH; i++) {
        Int_data += Char_array[i];
      }
      Int_data /= A_LENGTH;
    
      // ...sum of 'chars' divided by their number gives 'char' again (=average)
      Result = Int_data;    // casting, better explicitly: (unsigned char)Int_data
    
      my_function_A51();                  // call external function without parameters
      my_regpar_function_A51(Char_idata); // call external function with parameter(s)
    
      while(1); // stop here forever
    }
    

    and "Test_h.H" header file:
    // put SFR and other definitions here (examples here)
    sfr ACC = 0xE0;                 // accumulator SFR address
    sfr PSW = 0xD0;                 // Program Status Register SFR address
    
    sbit ACC3 = ACC^3;              // bit ACC.0 in assembler
    sbit CY = PSW^7;                // bit Carry Flag - 7th bit of bitaddressable register PSW
                                    // bitaddressable SFRs have address' lower nibble 0 or 8
    
    sfr TL2 = 0xCC;                 // if LSByte address of a 16-bit SFR register (here Timer2)
    sfr TH2 = 0xCD;                 // is by 1 lower than its MSByte address,
    sfr16 TIMER2 = 0xCC; // =TL2    // then sfr16 can be defined for such an SFR register
                                    // and compiler will arrange everything else
    
    sfr DPL = 0x82;
    sfr DPH = 0x83;
    sfr16 DPTR = 0x82;
                                    // miscellaneous constants or preprocessor macro definitions:
    #define A_LENGTH        5       // size of the array "Char_array"
    

    I am sorry if it is too long.
    Copy and study it. Hope it helps you.

    Best wishes!
    Eric

Children