On the wikpedia page about .COM files https://en.wikipedia.org/wiki/COM_file it reads:
.COM files in DOS set all x86 segment registers to the same value and the SP (stack pointer) register to 0xFFFE, thus the stack begins at the very top of the memory segment and works down from there.
But this actually sets the stack to begin one word below the top of the segment. When pushing a value on the stack the CPU will decrement SP to 0xFFFC and store the value there, thus wasting the top word of the segment. What is the reason for DOS not setting SP to 0 instead?
In 8086, the main stack register is called stack pointer - SP. The stack segment register (SS) is usually used to store information about the memory segment that stores the call stack of currently executed program. SP points to current stack top.
The base pointer is conventionally used to mark the start of a function's stack frame, or the area of the stack managed by that function. Local variables are stored below the base pointer and above the stack pointer.
A stack pointer is a small register that stores the memory address of the last data element added to the stack or, in some cases, the first available address in the stack.
This is for compatibility with CP/M.
In CP/M you could simply return from your program using ret
and your program would exit cleanly. This was achieved by having a 0x0000
at the top of the stack, and having an int 20h
instruction at address 0x0000
. Even though int 20h
is DOS' official way to quit a program, the option to quit the program using call 0
was kept from CP/M, and the outermost-scope ret
works the same as well since it returns to 0
.
In order to have that 0x0000
word at the top of the stack, you need to start the usable stack 2 bytes further down, obviously. That's why SP
is initially at 0xFFFE
, pointing to that 0x0000
word which in turn points to the int 20h
instruction.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With