9

I know that when an .COM file is loaded, DOS loads its contents into memory, sets the segment registers (CS, DS and SS) to point to the 64KB segment and then performs a jmp to the starting address. The program can then use that segment however it pleases, but how exactly would it actually use it in practice (where is the stack, heap, data, and code)?

1 Answer 1

9

TL;DR: MS-DOS does not assume any memory layout.

It depends on programming language, language runtime and application code.


The program can then use that segment however it pleases,

Exactly that is how they do it. Each in its own way. The only common (since forced) is where the (start) code is loaded. MS-DOS does not make any assumptions beside jumping to CS:100h when execution begins.

The COM format and it's TINY memory model (*1) was introduced to easy conversion of 8-bit (8080/Z80) software by offering a close setup. In fact, Digital Research called it the 8080 memory model in CP/M-86 documentation.

but how exactly would it actually use it in practice (where is the stack, heap, data, and code)?

This depends on the language used as well as what is needed. Like not every program has a heap. As said, MS-DOS does not give any rules or guidelines here.

This is as well true for more complex .EXE files which just allows to start execution on a different address as well as setting up SS:SP to a value relative to the PSP.

In Detail:

When execution starts, MS-DOS guarantees the following values:

  • AL - 00 if first FCB has a drive letter
  • AH - 00 if second FCB has a drive letter
  • DS -> PSP-segment
  • ES -> PSP-segment
  • SS:SP
    • For EXE -> Segment/stack pointer as defined in MZ-header
    • For COM -> SS -> PSP-segment, SP -> 0FFFEh (*2)
  • CS:IP
    • For EXE -> Entry point as defined in MZ-header
    • For COM -> CS -> PSP-segment, IP -> 0100h

For EXE sizes of the separate stack segment is taken from the header.

The New Executable for Windows (and later) differ by loading registers different:

  • AX -> Environment segment
  • BX -> Command line (offset within environment segment, important for long command lines)
  • CX - Size of data segment
  • ES - 0 (!)
  • DS - Data segment
  • SS -> Stack segment
  • SP -> Initial SP as defined in NE header
  • CS:IP -> Entry point as defined in NE header

Size of the separate segments (Data/Stack) is again taken from header fields.

What to do with all of this - or how the memory is structured into segments - is up to the program loaded, so essentially made up by each compiler as it wishes.


*1 - Except, the stack segment was always allocated outside - then again, the CMD loader format was already more capable than COM or EXE as well.

*2 - AFAIR (!) this differs when loading a program with less than 64 KiB of available memory. Then SP is set to the upper end of available memory minus 2.

13
  • 1
    So that means that when a .COM file is loaded into memory, SP points to some random trash offset within the segment (so you don't even have a working stack) and you need to set up the memory as you see fit? Seems kind of difficult to do in assembly (which is what I am trying to do), if you get one address wrong there is no seg-fault in DOS.
    – DarkAtom
    Commented Apr 28, 2020 at 10:17
  • 1
    @DarkAtom It's the same way it has been on 8080/Z80 systems. The COM format was introduced to ease conversion of 8 bit software. SP isn't random, but simply put to the upper end of the PSP segment (I added details). And yes, it's easy to screw it in assembly, but that's true for any other register and setup. Come on, you're doing assembly to get all freedom, no need for a nanny-OS :) When doing assembly it's safe to assume as little as possible.
    – Raffzahn
    Commented Apr 28, 2020 at 10:32
  • 2
    @DarkAtom When doing a COM program, you may think about it somewhat like a classic 8 bit computer.. You'll get 64 KiB of RAM (hopefully) and execution starts at 100h. the rest is up to you.
    – Raffzahn
    Commented Apr 28, 2020 at 10:34
  • Was there not even any memory mapped IO or ROM? Commented Apr 28, 2020 at 11:46
  • 1
    @RaffzahnThe machines I grew up on in the era of the first PCs didn't even have a way for the ROM or memory mapped hardware to not be visible to every machine code program. At least the ones I remember more about. But they also didn't have segments so I never grokked them very well. Commented Apr 28, 2020 at 12:15

You must log in to answer this question.

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