4

As per my understanding, Data Segment consists of 2 parts.

 1. Initialized segment.
    a. Read Only.
    b. Read/Write.
 2. Uninitialized segment.
  • The Read/Write memory is for variables declared at file scope as well as static local variables.
  • The Read only memory is for constants such as strings.

Example:

int main(void)
{
   char* cptr = "Hello"; // The string "Hello" will sit in 'Read only' memory.
   //cptr[2] = 'Z'; // Gives seg fault. 
   ...
   return 0;
}

My question is, Is 'Read-only' memory only used to store string constants?

NJMR
  • 1,886
  • 1
  • 27
  • 46
  • 6
    I don't know where have got your understanding, but it is wrong. BSS is a part of DATA section(R/W), containing statically allocated data to be initialized as zeros. That's all. – Eugene Sh. Aug 31 '16 at 14:34
  • 1
    Read-only memory may also be used to store `const` qualified variables. – Ian Abbott Aug 31 '16 at 14:34
  • @IanAbbott: const qualified local variables sit on stack I guess. Also, the const qualified local variable will go out of the memory once the stack fram deleted (once the function returns). – NJMR Aug 31 '16 at 14:38
  • 1
    The read-only segment never stores `const` qualified *variables*, it only stores actual constants. – Cody Gray - on strike Aug 31 '16 at 14:44
  • @NJMR sorry, I meant const qualified variables of static storage duration. – Ian Abbott Aug 31 '16 at 14:44
  • @CodyGray That's a C/C++ thing. C calls them variables, even though they are constant. – Ian Abbott Aug 31 '16 at 14:45
  • @CodyGray: in the example const int i = 5; , the value 5 can be hard coded into code as it is never going to change. Why to store the value in memory? – NJMR Aug 31 '16 at 14:45
  • Constant folding happens before the linker ever sees the code, so that example is not relevant. Sorry, @Ian, you're right. The question doesn't make clear which one he's asking about. The C standard is even more strict here about `const` values than C++, if I remember correctly. – Cody Gray - on strike Aug 31 '16 at 14:48
  • @NJMR The compiler is free to do what it likes if the variables have no external linkage, but if your `const int i = 5;` is declared outside a function, it has external linkage, so needs storage. – Ian Abbott Aug 31 '16 at 14:49
  • @CodyGray: I was referring to C. Will remove the C++ tag – NJMR Aug 31 '16 at 14:49
  • @DevSolar, the entire data segment doesn't have to be read-only just because the program is running from ROM. The initialization code would start by copying the read-write portion into RAM, just like it gets loaded from disk to RAM on a normal PC. – Wyzard Aug 31 '16 at 14:55
  • @DevSolar When the program is in the ROM, the data segment is usually relocated to RAM, by specifying the "load address" parameter in the linker script. – Eugene Sh. Aug 31 '16 at 14:57
  • Deleted my comment. Obviously my error, sorry. – DevSolar Aug 31 '16 at 14:59
  • 1
    @EugeneSh. No, BSS is _not_ part of DATA. They are distinct. DATA is for `int x = 5` and BSS is for `int y`. BSS has no static initializer to zero. Try creating a program with `int x[10000000000]` and do `ls -l` on the executable. The simplified layout of a program is `CODE|DATA|BSS|sbrk|stack`. On old systems, BSS was inited by the OS to 0 via `memset(bss,0,sizeof(bss)`, but now it uses copy-on-write from a "zero page". See my answer: http://stackoverflow.com/questions/37047977/which-segments-are-affected-by-a-copy-on-write/37060802#37060802 – Craig Estey Aug 31 '16 at 18:49
  • 1
    @CraigEstey You are talking about one specific architecture, I am talking in general. BSS is still initialized in the startup code for most embedded architectures. BSS and DATA sections are usually physically distinct (but often adjacent) regions, but the only difference is the initialization scheme. – Eugene Sh. Aug 31 '16 at 18:56
  • 1
    @EugeneSh. Yes, and I mentioned the `memset` option [which could be done by `crt0.o` or some such--left out of my 1st cmt for space reasons]. So, I think we're agreeing, but your original cmt _did_ say: _"BSS is a part of DATA section(R/W)"_ – Craig Estey Aug 31 '16 at 19:03
  • @CraigEstey Yes, it was a bit misleading. – Eugene Sh. Aug 31 '16 at 19:04
  • 1
    `gcc` will put it into `.rodata`. You can verify that with `elfcat --section-name .rodata the_ELF` for example. – Petr Skocik Sep 01 '16 at 21:41

1 Answers1

7

You are right, almost... there are three kinds of global static data in a program:

  • Initialized data, read only. Not only reserved for constant string, but for all types of const global data. It is not necessarily in the data section, it can be in the text section of the program (normally the .rodata segment), as it is normally not modifiable by a program.
  • Initialized data, read write. Normally in the data section of the program (.data segment).
  • Uninitialized data, read write. Normally in the data section of the program. The difference with the previous is that the executable doesn't include its contents, only the size, as they are initialized to a fixed known value (zero) and there is not a table of initializers in the executable file. Normally, the compiler/linker constructs a segment for this purpose in which it accumulates only the size required by the component modules (the .bss segment).
Luis Colorado
  • 10,974
  • 1
  • 16
  • 31