I have the sample of an EXE file with code, data and a stack. I built it fully by hand and set up its stack in the program's code, also by hand.
They all (data and stack variables) are referenced relative to the position after the paragraphs of the MZ header.
I have included the file SAVEMEG.DAT to show the exact position and layout in memory of the EXE when loaded into memory. We just need to find the string "
This is a command line to find the start and the end of" to find the sample command line of this program and its PSP as a result.
We can see that the EXE loader just interprets the EXE header, removes it from the image to load (normally 32 bytes long). After removing it, it generates a 256-byte PSP at the start of a segment and then loads the rest of the EXE as indicated by the size of the EXE in the MZ header as if it was a COM file but that can be more than 64K in size.
Obviously each compiler will have its own techniques to be able to use code and data among several segments, with a structure and techniques very similar to those used for being able to call and reference BIOS code and data.
But since this EXE is made fully by hand (without compilers or linkers involved), we will have to develop and maintain our own techniques to achieve the same.
We could have also created a COM file loader, then just have loaded a COM file greater than 64K. With that, we would have loaded a big COM file that supplies the vast majority of needs of a regular EXE file.
With this skeleton we can now start to learn bit by bit more practical things, like loading and executing VxD drivers all by ourselves.
However, I need to investigate and document how to implement and use relocations, which will surely be aboundantly used in VxDs.
Also, it will help to better understand LE (used by VxDs) and NE EXEs (used by Win16).
With that, along with the information about building and implementing GUIs, we could start making simple 16-bit programs that contain WinAPI functions implemented by us and now treat the WinAPI as yet another library ported natively to DOS and then to our own OSes.
Main source code:http://archive.org/download/tmp_tests/MZ_EXE/_TMP_/MZ_EXE_SAVEMEG/src/savemeg.asmFull source code:http://archive.org/download/tmp_tests/MZ_EXE/_TMP_/MZ_EXE_SAVEMEG.zipSample memory disposition of the EXE in memory (it starts with the 256-byte PSP at physical offset 0x1920):http://archive.org/download/tmp_tests/MZ_EXE/_TMP_/MZ_EXE_SAVEMEG/src/SAVEMEG.DAT