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

How do I get the bit address in Keil C

Hi,

I want to know the address of a bit variable.
For example:

bit gBit;
func()
{
  printf("%d", &gBit);
}
How do I know where the variable gBit is allocated by the linker in run time?

Parents Reply Children
  • but it is very inconvenient to manually update all the addresses of the bit variables every time you rebuild the program

    There may be ways (I can think of a few) but they are all application dependent.

    So I can give you no answer till you state WHY you need to know the address of the bits

    Erik

  • unsigned char bdata mybyte;
    sbit zero=mybyte^0;
    sbit one=mybyte^1;

    void main(void)
    {
    printf("mybyte=%p\n",&mybyte);

    while(1);
    }

  • You can access the bit variable at any time simply by using its name:

    mybit = 1;

    "mybit" is the address of the bit variable, automatically updated by the linker. No manual updates are needed; it's all automatic.

    Of course you knew that. So tell us what you are really trying to do. It obviously involves something outside the scope of just a C program, so you'll need to supply the details.

    The 8051 architecture does not support the notion of a pointer-to-bit, so bits do not really have accessible addresses. You'd have to have von Neumann memory and self-modifying code to change them at run time.

    If you're trying to share memory with some other bit of code or external device, so that a bit needs a well-known location, it's probably better to specify the address for the linker, rather than repeatedly look up the address the linker chooses and update all the other references.

  • This is what I am trying to do

    foo()
    {
      bit	Finish = FALSE;
    
      //pass the bit address to interrupt service routine(ISR)
      //the ISR routine will set this bit to TRUE when some event occurs
      Reg2ISR(&Finish);
    
      while( !Finish ) //waiting for the ISR routine to set this bit to true
        ;
    }
    

  • This is what I am trying to do

    foo()
    {
      bit	Finish = FALSE;
    
      //pass the bit address to interrupt service routine(ISR)
      //the ISR routine will set this bit to TRUE when some event occurs
      Reg2ISR(&Finish);
    
      while( !Finish ) //waiting for the ISR routine to set this bit to true
        ;
    }
    
    Each bit in the bit addressable area has an address, ranging from 0x00 to 0x7F. As long as I can get this address, I can assign value to the bit of that address.

  • As long as I can get this address, I can assign value to the bit of that address.

    No, you can't. More to the point, the 8051 can't do that. As a previous reply already pointed out to you: the '51 doesn't have the concept of a pointer to a bit variable. Or, to put in terms of assembly code: there is no indirect addressing mode for single bits, only direct addressing.

    A bit variable simply can't be used the way you want it to. Use a byte instead.

  • Of course it can be done in 8051 otherwise how the compiler initialize all the global bit variables before the main function is called?

    When your program is compiled and linked, Keil C will build a data structure called C_INITSEG. This data structure stores all the global variables that need to be initialized before the main function is called. So it also records all the addresses of bit variables that need to initialized before the main function is called. By using this address of the bit variable, it can give the bit variable initial value.

  • If you're so sure of your understanding, why don't you just go ahead an look into C_INITSEG to check what the compiler actually does? Or tell me the opcode of the machine instruction accessing a bit indirectly?

  • If I read this correctly, the OP is of the school where it is taught "If you use a global address, you will die"

    Access to a bit in main and an interrupt can be accomplished simply by making the bit declaration global.

    Erik

  • So it also records all the addresses of bit variables that need to initialized before the main function is called. By using this address of the bit variable, it can give the bit variable initial value.

    The initialization code converts the bit address into a byte.bit address and then uses and and or to mask and set the bit accordingly.

    There is no instruction on the 8051 that supports indirect access to bits. It has to be done manually.

    Jon

  • The initialization code converts the bit address into a byte.bit address and then uses and and or to mask and set the bit accordingly

    Jon, you scared me there. I had a look and
    GBvfdBusy = TRUE;
    does, indeed, compile to
    SETB GBvfdBusy

    wiping sweat off forhead

    Erik

  • I'm talking about global bit variable initialization.

    We would never do something like this for local bit initialization (which use the SETB and CLR instructions).

    Jon

  • my example above IS a global bit.

  • Just got it

    two statements in one heap

    the bit address is converted into a byte.bit address before it is used

    The initialization code ... uses and and or to mask and set the bit accordingly