This is one area that confuses me a lot. so a C program is normally divided into segments when running in memory, the code goes into the CS while global data goes into DS, local data is placed in a 16-bit Real mode environment these segments have different values while in 32-bit protected mode all the segments are set to zero,how then does the application differentiate between its code and data in memory in 32-bit mode and is the protection achieved through software(the OS) or is it implemented by the hardware automatically when you switch to 32-bit mode??
Posted on 2010-12-16 04:31:26 by ashken
The protection is handled by the hardware. You can control the mapping and access of the memory per memory page (usually 4 kb).
The CPU will generate an interrupt when your application tries to do something that the memory protection does not allow. The OS will then handle this interrupt, and take the appropriate action.

For example, virtual memory is implemented in this way. Memory is marked as inaccessible when it is swapped out to disk. When you try to access it, it will generate an interrupt. The OS will then see that the memory that the application tried to access is swapped out to disk. It will page it back into physical memory, and make the memory accessible, then transfer control back to the application.

So in a way it's a bit of both. There is hardware support for basic memory protection, but the OS is responsible for the actual management of the protection, and handling any page fault interrupts in a sensible way.
Posted on 2010-12-16 10:14:49 by Scali
Ashken, double check your segment values as I highly doubt that they are set to zero as you had indicated.  Your code segement register CS is most likely one value while the DS/ES/SS are normally set to another value.  FS and GS probably contain different values as well. None of the segment registers should contain a zero.
Posted on 2010-12-16 19:06:45 by p1ranha
what i mentioned is not something i know at a practical level but i read somewhere that that's what happens in major operating systems like Linux and windows. assuming only physical memory and a 32-bit computer, addresses start from 0x00000000 to 0xFFFFFFFF thats approx a maximum of 4GB. i read that they set all segment address to zero so that each segment can be as large as 4GB as compared to real mode where a single segment is only 65KB
Posted on 2010-12-17 02:16:40 by ashken
isn't it 64kb ?.. not 65kb..

pedantic sure, but sometimes its right to get the numbers right, otherwise your calculations get skewed
Posted on 2010-12-17 02:45:03 by evlncrn8
Depends on how you define kb - is it 1024 bytes, or 1000?
Really hate how idiot marketers apply metric conversions to our computing number systems..
I believe the current convention is that K = 1024, k = 1000, B = byte, b = bit
Posted on 2010-12-17 05:08:01 by Homer
65535 - if we're going to be nit-picky. :)



Ashken... to clarify... the number in the segment register will not be zero (defined as "invalid selector"), but the "base" field in the descriptor, to which the selector points, is zero (in all known OSen). The "limit" field is "usually" 0FFFFFFFFh in pmode, but 0FFFFh in real mode. The "limit" field is the only(?) one honored in real mode. It is possible to switch briefly to pmode, set segregs to a selector with a larger "limit", and hop back to real mode - the so-called "Flat Real Mode"/"Voodoo Mode"/"Unreal Mode". I like the name "relimited real mode". Only available starting from "real real mode", not "v86" mode... which is the usual case, these days, so not very useful.


Posted on 2010-12-17 08:13:03 by fbkotler

65535 - if we're going to be nit-picky. :)

Well no, you get 16 bits, which can represent any number between 0 and 65535. This is a total of 65536 different values.
Posted on 2010-12-17 13:00:50 by Scali
True enough... but the "limit" (if that's what we're talking about) would be 64k -1... or 64K-1... or whatever... I guess the original "65KB" typo was "size", so you're right. I stand corrected.


Posted on 2010-12-17 13:32:58 by fbkotler
Well, put it another way... K in a binary context stands for 2^10 = 1024.
So literally 64K means 64*1024 = 65536, regardless of whether you're talking about 'range', 'limit' or anything.
Posted on 2010-12-18 08:35:34 by Scali
The division of segments depends how you organize your program. In ASM you are free to declare your own data structures; it is much easier than in any High Level Language.
Some EXE file formats support allocation of some segment registers to defined segments, like DOS-MZ, WIN32-PE, OS-2-LE/LX, Linux-ELF...
In general almost any computer is designed according to the "Von Neumann architecture":,,
where the main memory can be considered as a long string of bytes which can be separated into segments with different access rights.
For example it is possible to use use a program segment as data storage if you set access rights properly. This spares declarations of additional segments and separate data storage:

; ...
mov eax,initval
progvar equ dword ptr $-4
; ...
add progvar,addval

Here is an overview how segments can be accessed according to their declaration (16Bit)
Posted on 2010-12-19 16:28:08 by TasmDev

From what I've learnt about memory models, that picture is somewhat wrong. Stack is always no more than 64 KiB, its segment can be overlayed with data (DGROUP to be exact), but only in tiny model this is required: any other model can have separate stack segment. 1 MiB stack can be maintained, for a while (one can embed proper adjustments for ss after each stack-related operation), but this looks like overkill.
Posted on 2010-12-20 13:17:20 by baldr
Stack is always no more than 64 KiB

That might not be true. For example, Borlands "Turbo Vision" utilized stack more than 64kB with FAR-calls to subroutines and FAR pointers to data structures, too. Also any protected mode software like HXDOS uses similar memory schemes. Please refer to the Open Watcom manual file "%WATCOM%\BINNT\CLR.HLP", topic "Advanced Types"-"Pointers".
Posted on 2011-01-11 18:13:06 by TasmDev
setting up a hook on stack overflow indicates a guard page with seh trap... we can deliberately not allocate stack space on a proc, and chances are with no effort, we will raise an exception we can trap.
hooking stack allocations is non trivial.
once you do though, creating a filo buffer aka object heap is dead easy.
Posted on 2012-06-26 04:42:21 by Homer