473,396 Members | 1,784 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Automatic variables + stack

Hi,

I have gone through a few posts on this topic in the forum and seem to get more confused.

I write a simple function in C which has local/automatic variables say a,b,c

Now from what i could gather from the forum posts is that the sections (data,code,stack,heap etc) are not a part of the C standard.

So, suppose i decide to place my function in the bss segment.

Now during execution there will be a stack frame associated with this function which will be created when the function is called and destroyed when the function exits.

The stack frame will contain the local variables for the function? If so then is the variable present in the stack frame a copy from whichever section the function is placed in? It cant be a pointer to that section as this would modify the value over there right?

I am just starting to get into the internals of C and hence there might be mistakes in what i wrote.

Also, if anyone could point me to a good resource for clearing such doubts it would be really really helpful
Feb 20 '10 #1
8 3468
donbock
2,426 Expert 2GB
The C Standard provides rules intended to insure that the behavior of a given program is predictable. It does not concerrn itself with how any given compiler/processor implementation achieves that predictable behavior.

Linker sections such as bss, text, data are not part of the Standard. Neither is a stack. Nevertheless, these are common means used to implement compilers that achieve Standard-mandated behavior. Since these things are not part of the Standard it follows that they are not standardized. The precise details of what they are and how they are implemented can and do vary from one implementation to another. That means that you should be a little skeptical of anything we tell you -- your particular target environment might be different.

That said, in general ...
  • text section contains the processor instructions; and sometimes static const variables.
  • data section contains initialiazed variables.
  • bss section contains uninitialized variables; that is, variables that are implicitly initialized to zero.
  • crt0 (traditionally called crt.0) is a block of executable code that runs before main. It writes the initial values into data and fills bss with zero; then it calls your main function.
These things all work behind the scenes. You can trust them to work properly -- you don't have to pull back the curtain unless you're working with an embedded processor. In that case, you need to coerce data and bss to reside in RAM, you need to coerce text to reside in flash memory, and you need to worry about how to get your program into the flash memory. For safety-critical systems you may have to execute an assembly-language selftest routine before allowing crt0 to run. These sorts of things are all exquisitely implementation-dependent.

By the way, you probably can't (and certainly shouldn't) place your function in the bss segment. Depending on what happens first, crt0 may overwrite the instructions of your function with zeroes. Typical run-time environments will trap attempts to write into text section to protect the instructions from being overwritten by an errant pointer (that's what "segmentation fault" means) -- but you would be giving up that protection.

Stack frames are a common way to implement parameter passing, function return, and automatic variables. However, there are other ways to do it. You can't make any assumptions about how your particular implementation does it.

Are you currently learning how to write programs in C? If so, then you are best advised to not worry about linker sections and stack frames.

Are you studying the design of compilers and run-time systems? If so, then you will want more details. Just remember to be a little skeptical about whether any particular detail applies to any particular compiler/processor implementation.
Feb 20 '10 #2
Well i have some experience in writing C programs but never thought about what happens between the time i run the compiler to the time i run the final executable. But now that i am shifting to embedded systems i feel i should know whats happening under the hood. Any good reference for this would be helpful. I am currently looking at ARM based systems.
Feb 20 '10 #3
donbock
2,426 Expert 2GB
As I said, this is different for each environment. The best reference may well be tthe documentation for your ARM development suite.

I haven't done any development for ARM systems. Post the name of your development suite -- maybe somebody is familiar with it.
Feb 20 '10 #4
alexis4
113 100+
Let me take a wild guess: you can't even compile a 1-line project, because you get an error on stack and heap. And a more wild guess: you are using IAR Embedded Workbench!

Now from what i could gather from the forum posts is that the sections (data,code,stack,heap etc) are not a part of the C standard.

So, suppose i decide to place my function in the bss segment.
In embedded software, the BSS segment is mapped into "Uninitialized RAM" that in fact is initialized to zero by the C runtime before main () is entered.
http://en.wikipedia.org/wiki/.bss

So you try to place a code segment in a RAM block or do you mean that you are placing the VARIABLES of this function into the RAM block?

Furthermore, I really don't know if the terms "stack" and "heap" are part of the C standard, but they have specific roles; storing local and allocated memory space respectively. Stack is strongly familiar to embedded developers and especially assembly coders. A FIFO space in memory, where you store not exactly temporary values, but values you need to restore at a later time. These would be variables from a function which called another function, or system settings (registers), so that you can restore them at a later time.

About "code" and "data': when you hear "code", then "FLASH" is the first thing comes in mind. When you say "data", "RAM" comes in mind but this is not always the case. You can store data in EEPROM (part of ROM) and even in FLASH (code memory!). In the last case, your data would become part of your code. Why would I need that you might say... Because FLASH is always greater than RAM, so you want to keep RAM as "clean" as possible. Thus when you have data that won't change during runtime, you declare them as "const" and they are automatically stored in flash.

So if for example you have a 4x20 LCD, this means 80 characters per message. If you have 10 messages, you would need 800 bytes of RAM, a catastrophic case if you are using small controllers. There are also reduced RAM techniques for that but the proper thing is to put them in FLASH.

The above are not the internals of C. There are assembly developers who don't even know a single C command, but they know all the above (except heap) and actually they now them better than C developers, because of assembly's nature. These are the ABC of Embedded Systems. If you can't manage memory succesfully you won't succeed your projects, even if you are an advanced C programmer. For sure you can use bigger controllers but as you may know, a controller is usually one of the most expensive parts of a board. So the smaller it is, the cheaper your board will be!
Feb 20 '10 #5
Ok i definitely need to read up on the sections properly i am confused about that.

What about the second part of my question concerning the stack frame? This i presume would be same even in non-embedded codes. So, when a stack frame is created in the background when a function call is made does the stack frame contain all the variables declared inside that function (except the static ones) or can i have the local function variables somewhere else in memory and the stack frame would somehow get a copy of that location?
Feb 20 '10 #6
alexis4
113 100+
So, when a stack frame is created in the background when a function call is made does the stack frame contain all the variables declared inside that function (except the static ones) or can i have the local function variables somewhere else in memory and the stack frame would somehow get a copy of that location?
In C enviroments, the term "stack" is not exactly the same with embedded systems. Stack is derived in smaller parts. There is data stack and return stack (maybe there are more, but I am familiar with these two types). Return stack (rstack) holds return addresses of function calls and interrupt routines. You are propably referring to data stack (cstack).

I don't know if it contains all the variables, I am not sure. A C expert would give you a safer answer on that. Propably yes, because if you do not allocate enough space for cstack, then the stack will overwrite another segment in the data area. This is your responsibility, although your debugger will most likely give you a warning during runtime.

Undoubtedly your compiler will either have settings for stack size, or takes these settings as external input from a file. All ARM enviroments I have seen integrate these settings inside their menu.

If you have compilation problems, you can do this: give the maximum possible stack size. You can find that in your compiler's user guide. If you pass this size you will get a compiler error. Run your program and see what happens. I usually use 32 bytes cstack and 16 bytes heap in small programs, although I do not need them all. This is because in embedded code, you strongly need global variables because if you store hardware values, you need to read them from multiple functions.
Feb 20 '10 #7
Banfa
9,065 Expert Mod 8TB
The C standard makes no mention of a stack or stack frames it just describes the behaviour of various types of variable as Don has already stated.

However enough platforms implement stacks and stack frames that they are worth understanding. Generally speaking a stack frame contains everything required to let a function execute. That would normally be interpreted as space for the function parameters (or a pointer to them), space for all the local variables and all the data required to return from the function. The data required to return from the function is at a minimum the return address for the instruction pointer but often includes other processor registers, may be even all of them and the address of the previous stack frame.

In some micro-controllers, in my experience mainly low power self-contained ones, the return address stack is sometimes implemented as a separate hardware stack. This is finite in size and if used limits the number of function calls that can be made.

One of the differences between C and C++ is who has the responsibility for unwinding the stack, removing the stack frame. IIRC in C it is the called function, in C++ it is the calling function. This change was required in C++ to allow exceptions to work properly since an exception can cause a function to exit on any line of code.

So (in C) when a function is called the calling function does something like
  • pushes the processor state (registers) onto the stack
  • pushes the return address onto the stack
  • pushes the size of the current stack frame or an end of stack frame pointer onto the stack leaving space for the local variables of the called function
  • pushes the function parameters onto the stack

Note that this is very generalised, different platforms will push slightly different things and in a different order, this is just the sort of things that get pushed.

On return the called function restores the processor state from the calling function and jumps to the return address.

Many processors have a register dedicated to storing the current stack frame.

The return value of a function might be passed via the stack or again might be passed in a register.


Once you have a handle on how a stack frame is used to facilitate a function call then you are at least half way to understanding how interrupts and multi-threading is often implemented in an embedded environment.

When an interrupt occurs the process pushes an interrupt frame onto the stack. This is akin to a stack frame but contains no space for parameters, local data or return value because execution is not jumping to a function but rather a completely different context. The the processor jumps to the relevant interrupt handler, note in the case of an interrupt the processor may also change some processor registers or flags in indicate that it is running an interrupt routine. It may even have a separate interrupt stack that it uses while processing a interrupt routine. Once the interrupt finishes the processor pops its original state from the stack and continues executing the normal code where it left off.

Multi-threading operates similarly often. Every thread has its own stack, when a task-switch happens the processor stores a task switching frame (similar in contents to an interrupt frame) on the stack of the current thread. Switches stack to the new threads stack and pops its state from that stack to continue running the new task from where it was last running it.

Assuming that any given platform you use has a stack then

Details of the stack frame and interrupt frame can be found in the platform (processor) documentation.

Details of the task switching frame might possibly be in the platform specific documentation for the OS that you are using but more often than not is not documented (at least in publicly available documentation).
Feb 21 '10 #8
donbock
2,426 Expert 2GB
@praetor
Recall that C allows a function to have any number of brace-delimited blocks; and that each such block could have its own private variables. It is possible that upon entry to a function a single stack frame is allocated to hold all of the variables of all of the blocks. It is also possible that an additional stack frame is allocated upon entry and released upon exit from each block. The first approach probably minimizes execution time and size of the code; the second approach probably minimizes stack usage. It is not unreasonable to think that a compiler for an embedded processor might have the ability to optimize stack usage.

You need to get documentation from your compiler vendor. You can't reliably infer what it does from a few observations.
Feb 22 '10 #9

Sign in to post your reply or Sign up for a free account.

Similar topics

13
by: Sunil | last post by:
Hi all, I want to know how good or bad it is using global variables i.e advantages and disadvantages of using global variables. Sunil.
28
by: Dennis | last post by:
I have a function which is called from a loop many times. In that function, I use three variables as counters and for other purposes. I can either use DIM for declaring the variables or Static. ...
58
by: Jorge Peixoto de Morais Neto | last post by:
I was reading the code of FFmpeg and it seems that they use malloc just too much. The problems and dangers of malloc are widely known. Malloc also has some overhead (although I don't know what is...
5
by: mike.m.schmidt | last post by:
Hello, I've been trying to optimize a piece of code that executes in 6 milliseconds. From what I have read, dynamically managing memory with new/malloc and delete/free is less efficient than...
25
by: sidd | last post by:
In the following code: int i = 5; ---it goes to .data segment int j; ---it goes to bss segment int main() { int c; int i = 5; ---stack
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.