在关于.COM文件的wikpedia页面上https://en.wikipedia.org/wiki/COM_file上面写着:
.DOS中的COM文件将所有x86段寄存器设置为相同的值,将SP(堆栈指针(寄存器设置为0xFFFE,因此堆栈从内存段的最顶部开始,并从那里开始工作
但这实际上将堆栈设置为从段顶部以下的一个单词开始。当在堆栈上推送一个值时,CPU会将SP递减到0xFFFC并将该值存储在那里,从而浪费段的顶部字。DOS不将SP设置为0的原因是什么?
这是为了与CP/M兼容。
在CP/M中,您可以简单地使用ret
从程序返回,然后您的程序将干净地退出。这是通过在堆栈的顶部具有0x0000
并且在地址0x0000
具有int 20h
指令来实现的。尽管int 20h
是DOS退出程序的官方方式,但使用call 0
退出程序的选项被保留在CP/M之外,最外层的作用域ret
也可以工作,因为它返回到0
。
显然,为了使0x0000
字位于堆栈的顶部,您需要将可用堆栈向下启动2个字节。这就是为什么SP
最初位于0xFFFE
,指向0x0000
字,而该字又指向int 20h
指令。