Understanding exactly where the exe code is stored during execution?

So I've just got done with some of Casey's videos explaining some of the in's and out's of windows memory management and how program's address spaces are basically divided up on 4KB page boundaries for which the OS will bring in and push out of RAM. After watching these I also noticed someone put up a link with some great talks by Mark Russinovich who goes into much more detail on how exactly windows manages memory. Within these talks, Mark goes into how the OS first begins a program. In the video, when talking about how windows first boots up a program's exe he states [paraphrasing], "Exe's are mapped into the address space. When something like notepad.exe is first started up, notepad.exe is mapped into the address space and then the first thread is created with a start address that points to the first line of code in notepad.exe. When this is run, a page fault is incurred and the system pulls in the first page of the exe into RAM and connects the RAM with the virtual memory of the notepad process and the tread continues".

What I'm confused about is what does he mean exe's are first 'mapped into the address space'? What address space is he talking about? In my mind, when he says 'a program's address space' I think he's referring to a program's virtual address space which, in the beginning, only lives within the exe file itself on disk (within the .code/text section of the exe correct?). If this is true, then how can a program map itself into it's own address space? According to Mark, the first page of a program isn't actually in RAM until part of the exe is already memory mapped 'somewhere' and the first line of the code is executed which then incurs the page fault and puts the first page of code into RAM.

Edited by Jason on Reason: Initial post
When new process is started then special data structure is created by operating system which contains whatever information is needed to manage the process. This data structure is OS internal data, process cannot access it directly. It contains information like how many (and where) memory pages are allocated, what files are opened, threads, etc. But you interact with it by using various system API's (CreateFile, VirtualAlloc, CreateThread, etc...).

how can a program map itself into it's own address space?
This is not done by program itself, this is done by OS. When it allocated all that internal data structure, it maps exe file to memory in newly allocated process.
Memory mapping a file means that from the point of view of the program a region of memory contains the same data as a file. You can get (mostly) the same effect by reading the entire file into memory however that prevents a few optimizations from happening.

One of the optimizations used with memory mapping is that the data is not actually read from disk until you try and access it. IMO that is both a blessing and a curse. For one you can get stalled unpredictably and uncontrollably if the disk is overburdened. You also cannot say that a region will not be needed any more.

Mapping the exe file into memory when it starts is done by the OS not the program itself. It will also set memory protection bits to prevent writing to the read-only bits (code and constants) and make sure the read-write bits (initialized globals) are not shared and only the code bits are allowed to be interpreted as code.


One of the optimizations used with memory mapping is that the data is not actually read from disk until you try and access it.


Okay so a page of a file, whether that be an exe or whatever, can be 'mapped' into physical RAM without any of that pages actual data from the disk being present? Until the program actually wants to touch and use that data? If so, then what is exactly stored in RAM if not the actual data from the disk? How does the OS know a page of physical RAM is occupied if no data was copied from disk?

Edited by Jason on
If so, then what is exactly stored in RAM if not the actual data from the disk?
At the point of mapping - nothing. Memory contents does not matter at the point of calling "map" operation.

How does the OS know a page of physical RAM is occupied if no data was copied from disk?
That's the job of OS/kernel - to maintain what is actually read into memory and what is not yet. The parts which are not loaded are simply marked as "not accessible". So any time user space code will try to read/write to these locations, page fault will occur and kernel will simply wait until loading is finished. And only then resume execution of users code.

Edited by Mārtiņš Možeiko on