在不同的时间,我都使用了两者
int 0x20
和
mov ah, 0x4c
int 0x21
作为结束16位汇编程序的方法。
但两者有什么区别?
编辑:感谢您的评论。关注Alexey对PSP(程序段前缀)的引用,得出this nugget from Microsoft MASM support。
这篇文章似乎表明,与返回代码相比,差异更大。
很高兴将接受的答案授予任何能够更明确地将两者结合在一起的人。
答案 0 :(得分:14)
首先,一些背景知识。 DOS使用中断21h进行系统调用。 AH用于解复用INT 21h提供的各种功能。当程序执行时,DOS将其置于256字节之前,称为PSP(程序段前缀),其中包含有关该过程的信息。
DOS中的原始退出功能是INT 21/AH=00
。现在,显然DOS开发人员决定从程序返回应该是一种退出程序的方法(这是来自CP / M吗?)。 RET
(近)从堆栈中弹出一个单词并跳转到它。因此,在创建程序时,其堆栈以单词0000
开头。这是PSP的开始。因此,在PSP开始时,有代码来终止程序。为了保持较小的代码,INT 20h
充当MOV AH,00h ; INT 21h
的别名。
[编辑:这可以在下面的屏幕截图中看到。]
DOS 2.0从Unix中获取了许多东西,包括返回代码。因此,出现了一个新的INT 21h函数INT 21h/AH=4ch
,它接收返回代码以将其返回给操作系统。此功能还可用于EXE文件(AFAIR也是DOS 2.0中的新增功能),可以有多个段。先前的退出函数(INT 20h和INT 21h / 00)假设CS与COM程序上的程序启动时相同,也就是说,它指向程序之前的PSP 256字节。
[编辑:
历史记录:在CP / M上,退出程序有三种方法:
WBOOTF位置包含3个字节:1个字节用于跳转,2个字节用于跳转目标(BDOS中的WBOOT功能)。
在早期版本的CP / M中,调用BDOS功能0或跳转到WBOOT会导致部分CP / M从磁盘重新加载(热启动),并且随后会运行一些OS初始化; RETurning直接返回CCP(Console Command Processor,相当于COMMAND.COM),然后提示输入下一个命令行。 AFAIU,CP / M 3通常加载到ROM中,并返回到WBOOT位置,导致从ROM重新加载部分操作系统。
答案 1 :(得分:6)
答案 2 :(得分:1)
这就是我所知道的。
MOV AH, 0x4C
INT 0x21
结束正在运行的EXE文件,EXE文件必须以这种方式结束,因为代码段寄存器CS。纠正我,如果我错了,但如果你以这种方式结束COM文件,你会得到意想不到的结果(崩溃,挂起,重新启动等)。因此
INT 0x20
结束COM文件。
CS与在COM程序上的程序启动时相同,也就是说,它指向程序之前的PSP 256字节。 (CodeSegment InstructionPointer CS:IP,CS包含代码段)。是的,我们正在谈论寄存器,变量它们就像一个橱柜,我的工作就像你可以在抽屉里正确放置一些东西。 AX = 0000 BX = 0000 CX = 0000(CX由CL和CH组成)等。
我认为COM文件一般限制在64K以下。我认为第二个原因是COM文件没有DATA SEGMENT,它们确实有数据,但它与代码位于同一段。我认为他们除了CODE之外没有任何段,COM文件中的所有数据都存储在64K内。 EXE文件有一个段,一些EXE文件在使用正确的内存模型时可以有更多的段(CS:IP)(参见英特尔内存模型)。
CS=DS=SS
DS=SS
DS=SS
,多个代码段使用内存模型SMALL,EXE文件的限制为64K。 当使用更大的内存模型和更远的32位指针时,您可以处理超过64K(仍然有限)。我认为这是'技巧'。
现在每个人都在抱怨我为什么要使用EXE文件。以上是原因。内存模型来自维基百科。对于那些不在乎的人,我从专业人士那里学到了很多东西。彼得诺顿和约翰索哈。来自Norton Utilities(Norton Commander for DOS背后的人)。他有一本关于装配的书,比如“装配IBM-PC”。你应该阅读它,他解释得最好。他对我来说就像一位好老师。 Microsoft CodeView澄清了我很多。在DOS C中编程? Turbo C 2.0是您可以获得的最佳选择。哦,我不再编程了。