9

I am trying to understand Flat memory model and Segmented memory model.

Are Flat memory model and Segmented memory model determined by CPU architecture or OS or both?

Or are they not determined by either of CPU architecture and OS, but instead they are available options for programmers on any computer with any CPU architecture and installed OS?

If it is the latter, what kinds of programming need to consider Flat memory model and Segmented memory model? Assembly, C and/or other high-level programming languages?

Here are some quotes from Wikipeda that confuse me.

From http://en.wikipedia.org/wiki/Address_space#Memory_models:

Early x86 computers used the segmented memory model addresses based on a combination of two numbers: a memory segment, and an offset within that segment. Some segments were implicitly treated as code segments, dedicated for instructions, stack segments, or normal data segments. Although the usages were different, the segments did not have different memory protections reflecting this.

Now, many programmers prefer to use a flat memory model, in which all segments (segment registers) are generally set to zero, and only offsets are variable.

From http://en.wikipedia.org/wiki/Flat_memory_model#Comparison:

Flat memory model

  • Not suitable for general computing or multitasking operating systems, unless enhanced with additional memory management hardware/software; but this is almost always the case in modern CISC processors, which implement advanced memory management and protection technology over a flat memory model. Linux e.g. uses a flat memory model compare X86_memory_segmentation#Practices.

Segmented memory model

  • Implemented in original Intel 8086, 8088, 80186, 80286 and supported by 80386 and all subsequent x86 machines through to present day Pentium and Core 2 processors. This memory model has remained ever since in the x86 machines, which now provide multi-mode operation and rarely operate in the compatible segmented mode anyway.

4 Answers 4

10

The memory model in use is determined by two things:

  1. The CPU in use, and what modes it supports
  2. The Operating System and what it uses

From a programmer's point of view, unless you're working on kernel code, you get what the OS gives you. Which in most modern operating systems is a paged memory model.

For code that will execute on a modern operating system in userspace, the memory model as far as the process is concerned is flat. This is because the OS provides a virtual memory space to the process that hides all of the paging, swapping, and other things that can happen to memory. This layer of abstraction is quite, quite useful since it doesn't force programmers to play nice with memory for the good of the whole system.

Historically, this wasn't always the case.

Windows 3.1x, MacOS up to v9, and Novell NetWare all lacked some of the memory protections we take for granted in Linux/Windows/OSX. NetWare in specific had one big memory space it provided to all running code, so one bug that attempted to access memory it wasn't actually assigned could actually get that memory and more often than not crash the whole system. Programmers programming for NetWare had to be very careful about memory management for this reason, and to an extent that Linux/windows/OSX programmers don't need to bother with.

And yet even NetWare used a Paged Model of memory, it just didn't provide each process with a virtual memory-space, it gave it the actual memory space.

The memory model in use is not flexible for all programming but the closest to the hardware. Kernel programming and embedded device programming are the areas where such things are very important.

1
  • Thanks! If segmented memory model is not related to the different segments (BSS (Block Started by Symbol) segment, Text segment and Data segment) in an object file? I heard those segments in object files quite often (en.wikipedia.org/wiki/Object_file#Object_file_formats), so I guess they may not be related to the segments in segmented memory model, although they are all called "segments".
    – Tim
    Aug 7, 2011 at 0:31
6

"Memory model" is both a low-level and a (relatively) high-level concept.

Back in the olden days there was a bit of a "war" raging between processors with a segmented memory model and those with a "paged" or "mapped" memory model. The Burroughs B5000 series machines and the Plessey 250 used a segmented memory model with "capabilities" (or "descriptors"). That is, physical storage was not managed as conceptual fixed-size pages but rather variable-length segments, with each segment corresponding to some logical entity (eg, a procedure or an object). To address between segments "capability registers" were used that could only be loaded in a protected fashion and which contained the physical address of a segment, the length of the segment, and the authorizations (eg, read/write/execute) that the executing program was given to reference the segment.

These systems were happily running when "paged" systems were still struggling to get off the ground.

The original PC was based on the 8086 processor which was designed to support a poor-man's segmented architecture. There were, IIRC, four segment registers that could be selected to be added to a 16-bit general register value to produce a 20-bit address. The theory was that these registers would be managed in software somewhat similar to how the Burroughs and Plessey systems managed them with a bit more hardware support. But before good software could be produced to make use of this feature DOS was kludged onto the 8086, and so the feature was never really used effectively.

As to which is better, well, it doesn't matter anymore, since the segmented model doesn't exist in any "real" (non-experimental) environment. But back in the day the segmented model generally performed better and allowed the OS to be more robust. The major negative factor was that it imposed restrictions on compilers and, to an extent, programmers that were not consistent with the "Wild West" attitudes of many programmers then and now.

The "paged" model

A "paged" model assumes the address space is divided into "pages" of a certain size (though in some cases several different page sizes are supported). Generally the page size is somewhere between 256 bytes and 64k bytes (always a power of 2). It is also assumed that the hardware contains some sort of address translation support so that "logical" addresses (addresses in the program's "address space") can be mapped to "physical" addresses (addresses in RAM).

A paged model may be implemented for two main reasons:

  1. To allow multiple different threads/processes to have separate address spaces, each starting from "zero" (or some other standard address), and without requiring to OS to pre-allocate the entire possible address space for a thread/process as one contiguous chunk.
  2. To enable "virtual memory" by allowing individual pages in the logical address space to be "paged out" to disk, to be later reloaded if/when the program attempts to reference them.

There are also minor features of the page translation hardware that may be used, such as setting read/write/execute permissions, allowing some pages to be "shared" between processes/threads, etc.

The "flat" model

Ignoring the Harvard model, which was arguably the very first computer memory model, the flat von Neumann storage model was first model to achieve common use. This is basically that -- a "flat" address space of undistinguished words (not bytes until very late in the game) that began at address zero and continued upward to the "top" of available memory. Some portion of memory at the "bottom" or "top" of memory would be reserved for some sort of "loader", with the rest available to the single executing program. One program at a time ran, with the program able to use all but that small reserved RAM area.

Slowly things changed, to where the small reserved area became larger and held an operating system of sorts, but still only one program at a time. As time progressed still further, various tricks were invented to allow, eg, certain specialized programs to run in a "corner" of memory, permitting spooling programs, etc, to co-exist with the user's programs.

But the push for "multiprogramming" was exerting pressure. Some systems added crude address mapping hardware to enable multiple programs to each have their own address space. Other systems required that programs be "self relocating" so that they could run anywhere in memory vs being "linked" to a specific address.

Early Unix (among others) handled the multiprogramming job by "swapping" programs in and out: A program (loaded at address zero) would run until it "blocked" to do I/O, then it would be "swapped" (in its entirety, including all code and data) to disk and a different program "swapped" in.

But for the most part these techniques slowly evolved (or perhaps devolved) to various forms of page-mapping storage models.

3
  • Thanks! I wonder how paged model differ from segmented model and flat model?
    – Tim
    Aug 4, 2011 at 13:05
  • Is paged model not related to paging between main memory and hard disk in the virtual memory?
    – Tim
    Aug 4, 2011 at 14:36
  • AFAIK windows 3.x and 9x also swap the whole program out. Paging at that time is limited to windows NT
    – phuclv
    Feb 24, 2018 at 13:39
3

I'm a programmer, but not an embedded programmer who actually has to deal with memory models at this level, so take what I say with a grain of salt.

My understanding is that memory models are determined by the processor architecture. They'd be most relevant to a programmer working with assembly, low-level C, or anything that is close to the hardware. With many higher level languages, like Java or C#, there are abstractions that hide details like these from you, so you don't usually have to think about hardware memory models.

There are weird times when it does come up. It's my understanding that 32-bit x86 processors (for the last decade, at least) can access more than 4GB of memory using segments (PAE Mode), any many 32-bit OSes support it, but then the maximum amount of memory a single process can use is limited to 4GB, because most programs expect a flat memory model (and I doubt many modern OSes would allow them to expect anything else).

To clarify the quotes:

  1. Early x86 processors had a memory model that was a lot like a set of numbered drawers with smaller numbered compartments in them. To access a bit of memory, you'd have to specify the drawer number along with the compartment number. All the drawers were the same, some programmers would just decide to use one drawer for code, another for data, etc., but those decisions weren't dictated by the processor architecture. A flat memory model is like having exactly one drawer, so you just use the compartment number.

  2. Without extra features (like ones that prevent one program from using another program's memory), a flat memory model isn't suited for modern operating systems, but all modern desktop/server processors have had these features for decades.

  3. All x86 processors have modes that access memory just like an 8086, 80286, etc for backwards compatibility, but they're obsolete. Pretty much no one uses them anymore, and they always switch to more modern modes.

Hope this helps.

2
  • Thanks! (1) in 2 and 3, do you mean that since modern processors mostly have the features for memory protection, most modern architectures are using flat model by default, with back compatibility with segmented model? For example, when programming in C on modern x86, all pointers are implemented using flat model by GCC by default, while using segmented model is not default? (2) Does OS affect which model to use? In the quote "Linux e.g. uses a flat memory model" seems to imply some other OSes (perhaps Windows, Mac) may use segmented model?
    – Tim
    Aug 4, 2011 at 2:12
  • @Tim The backwards compatibility features are used by the OS if at all. Modern OSs don't let mere programs go to those modes because of how disruptive they are to the whole system. Aug 4, 2011 at 2:27
1

Memory segmentation is the division of computer's primary memory into segments or sections. Segments or sections are also used in object files of compiled programs when they are linked together into a program image, or when the image is loaded into memory. In a computer system using segmentation, a reference to a memory location includes a value that identifies a segment and an offset within that segment. Different segments may be created for different program modules, or for different classes of memory usage such as code and data segments. Certain segments may even be shared between programs

You must log in to answer this question.

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