0

Each program is separated into several segments like:

  • code segment
  • data segment
  • stack segment
  • heap segment

But who was responsible for that progression? The compiler and linker has to support that conversation to those segments.

  • was it first implemented by the compiler and linker developers and the early operating systems used it?

or

  • was it first implemented by the operating system developers and the compiler and linker developers needed an adjustment?
1

1 Answer 1

1

This was based partly on CPU design.  Into the 1980s, most computers had a 16-bit architecture, so a pointer could access a virtual address space of 216 (65536) bytes.  This was, naturally, considered to be too restrictive.  When the code segment is separated from the others, you can have 216 bytes worth of code (instructions) and 216 bytes worth of data, which is less bad.

The “data space” of a program/process (using the terms in the broadest possible sense) can include

  • Initialized data, including
    • Strings (e.g., printf("Hello, world\n");),
    • Initialized variables (e.g., int i = 42;), and
    • In some cases, constants used in code (e.g., y = x + 17;),
  • Non-initialized variables (e.g., int j;, char mydata[80]; in static/global contexts),
  • Dynamically allocated memory (malloc, new), and
  • Stack (function arguments, save/restore information, and local variables).

I may be leaving something out, but registers don’t really count (they are essentially a special case of non-initialized variables) and shared memory is beyond the scope of this discussion.  Note that, of the above, only the initialized data need to be saved in the executable file — space for non-initialized variables and the stack is automatically allocated by the OS when the program is executed.  So the compilers needed to keep track of initialized data and non-initialized variables separately.

Another wrinkle is that the Intel 8086 CPU (the great-great-grandfather of the Pentium) required each segment to be one big, contiguous block of memory.  The Unix kernel consists of one big block of code and one big block of data (initialized data and non-initialized variables), but it uses a separate stack for each process.  Therefore, the 8086 required the ability to have the stack in a different segment from all the other data.

There’s lots of information about this out there on the web.  For example, in Wikipedia:

Not the answer you're looking for? Browse other questions tagged .