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

functions variable mapping?

As I can see, the keil compiler doesnt use regular stack for functions, and all the local variables inside functions are mapped in global memory.
Is there a way, to make it behaive like a normal program should? I.E - create a local variables in ram,and destroy them, when the function ends?
Thank you.

  • Is there a way, to make it behaive like a normal program should? I.E - create a local variables in ram,and destroy them, when the function ends?

    yes, there is and, amazingly enough, that is how it works. That the stack is not involved does not disable thais.

    Erik

  • "As I can see, the keil compiler doesnt use regular stack for functions"

    It uses the stack for return addresses, and a few other things

    "all the local variables inside functions are mapped in global memory."

    and possibly some parameters, too.

    "Is there a way, to make it behaive like a normal program should?"

    What do you mean, "should"?
    There is nothing in the ANSI spec that requires any specific implementation of this!

    C51 works the way it does because of the nature of the 8051 processor. You can fight this if you wish, but you will get grossly inefficient code!
    Look up the 'reentrant' keyword extension...

    "create a local variables in ram,and destroy them, when the function ends?"

    The stack is still in RAM whichever way you do it!

    Also, stack-based compilers do not "destroy" variables when a function exits: the data remains in RAM (on the stack) - only the stack pointer is changed.
    This is why uninitialised variables can be so much fun...

    The way C51 works is effectively just having the tools do at build time what "conventional" implementations do on the stack at run time!

  • Is there a way, to make it behaive like a normal program should?

    Define "normal". Do you mean "like processors for desktop computers do it" ?

    That's not "normal". And the '51 is not a processor for a desktop computer, it's a microcontroller.

    Anyway. Andy said everything that should be said about this topic. Apart from reentrancy, there is pretty much no need for resorting to a slow, inefficient variables-on-stack approach.

  • "slow, inefficient variables-on-stack approach."

    Hmm... interesting.

    Indirect addressing will always be slower & use more code than direct addressing - on any processor.

    So a better question might be, "how can I get the speed & efficiency of C51's approach in other compilers?"!

    The thing is, using the stack makes life easier for the compiler; the C51 approach means, as previously noted, that the tools have to do all the hard work at build time - but the result is faster, tighter code!

    C51 has to do it this way, because of the architectural limitations of the 8051; other compilers just choose to take the easy way out - because they can!

  • Woa, so much nervious replies. Get easy on the coffee,ok?
    I will try to make myself clear this time.
    --
    When the function is called,it should create variables to use. It should use some pool ,and release it,after it is done (unless it's static variable,but i'm not talking about it).
    Now, if i'm having some parsing functions, i have to use one common pool, cant define array or other variables in function (nvm that one).

    "reentrant" key does make the function to do what i intend, but the assembly is so ugly, and it immediately involves so much bugs with optimization, that i have to disable it (optim.)

    About "slow-inneficient-stack-approach"
    Excuse me, but I have only 8k Ram,and i care less about couple of ms.
    So i prefer the function to do some pushing,popping,calling. The general question was - how do i make it? (Wihtout reentrant)

    PS. Erik -
    [yes, there is and, amazingly enough, that is how it works. That the stack is not involved does not disable thais.]

    Local variables are defined in stack. No stack - no local variables.

  • Yes,Adny - thank you.
    I understand, that nothing left to do, but to live with this.

  • "Excuse me, but I have only 8k Ram,and i care less about couple of ms."

    no you have only 248 bytes at max for stack
    Stack is always in IRAM on x51.
    So putting local vars on stack might be a bad idea.

    Thomas

  • Okay. So the only way is to define myself a pool of memory in global area , and use it from functions.
    Thank you.

  • Stack is always in IRAM on x51.

    Odd, the ADuC 8xx family can put the stack in XRAM.

  • When the function is called,it should create variables to use. It should use some pool ,and release it,after it is done (unless it's static variable,but i'm not talking about it).

    Have you read the chapters about memory overlaying in the compiler and linker docs ? Have you understood what exactly memory overlaying means and why it is the better way of creating local variables on a '51 ?

    The compiler does exactly what you describe above, _without_ using a stack.

    If you don't do things you shouldn't do anyway on a '51 (function pointers) or really need reentrancy, there is no reason to resort to using a stack.

    Local variables are defined in stack. No stack - no local variables.

    It is completely irrelevant _where_ local variables are. They are defined by exiting only within the scope of one function. Whether this is done by using a stack or using memory overlaying is of no concern.

    "reentrant" key does make the function to do what i intend, but the assembly is so ugly, and it immediately involves so much bugs with optimization, that i have to disable it (optim.)

    Using a stack leads to ugly assembly code on the '51 architecture. That's why the standard behavior of the C51 compiler is to use memory overlaying instead, a much, much more efficient and much, much less ugly approach.

  • The compiler does exactly what you describe above, _without_ using a stack.

    Why, then, when the code is compiled, and compiler shows me the sum of all memory used, all the local variables are counted as global?
    And if it exceeds 8k, wont let me compile (makes sense)

  • Why, then, when the code is compiled, and compiler shows me the sum of all memory used, all the local variables are counted as global?

    Did you enable memory overlaying as an optimization ?

    Are you using things that keep the linker from building a complete calling tree (function pointers) ?

    Also, the compiler does not do memory overlaying (it cannot, as it works on single files). What does the linker output say ?

    If overlaying is enabled and the linker can build a complete calling tree, and the memory used for the local variables and parameters is still equal to their sum, then no overlaying is possible and this is the amount of memory that is necessary, no matter whether you use a stack or overlaying. If you used a stack instead and allocated less memory than is used with the above method, you're asking for a stack overflow.

  • Yes. I am using a state machine, thus having function pointers.
    But the specifig function i am using , is not called by pointer.
    Or one function pointer will ruin the whole optimization?

  • Or one function pointer will ruin the whole optimization?

    Yes ! Because neither the compiler nor the linker will ever be able to unambiguosly figure out which function the pointer will point to at a certain point in the program, and therefore the linker cannot build a calling tree. Please re-read the chapters about memory overlaying and function pointers.

    Use a switch/case instead. Or, build the calling tree yourself, though that is probably the more complicated solution.

  • Thank you, Christoph, for your help.
    Now i know the problem, i will try to handle it.
    Thank you again.