为什么 DOS 在加载 .COM 文件后将 SP 寄存器设置为 0xFFFE?

Why does DOS set the SP register to 0xFFFE after loading a .COM file?

在有关 .COM 文件的维基百科页面上 https://en.wikipedia.org/wiki/COM_file 它显示:

.DOS 中的 COM 文件将所有 x86 段寄存器设置为相同的值,并将 SP(堆栈指针)寄存器设置为 0xFFFE,因此堆栈从内存段的最顶部开始并向下工作从那里开始。

但这实际上将堆栈设置为从段顶部下方的一个单词开始。当将一个值压入堆栈时,CPU 会将 SP 递减为 0xFFFC 并将该值存储在那里,从而浪费了该段的顶部字。 DOS 不将 SP 设置为 0 的原因是什么?

This is for compatibility with CP/M.

在 CP/M 中,您可以使用 ret 从您的程序中简单地 return,您的程序将干净地退出。这是通过在堆栈顶部设置 0x0000 并在地址 0x0000 处设置 int 20h 指令来实现的。尽管 int 20h 是 DOS 退出程序的官方方式,使用 call 0 退出程序的选项在 CP/M 中被保留,并且最外层范围 ret 起作用也一样,因为它 returns 到 0.

为了让 0x0000 字位于堆栈的顶部,显然,您需要将可用堆栈向下启动 2 个字节。这就是为什么 SP 最初位于 0xFFFE,指向 0x0000 字,而后者又指向 int 20h 指令。