Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 什么';使用int 0x20和int 0x21/ah=0x4C退出16位汇编程序之间的区别是什么?_Assembly_X86_Dos - Fatal编程技术网

Assembly 什么';使用int 0x20和int 0x21/ah=0x4C退出16位汇编程序之间的区别是什么?

Assembly 什么';使用int 0x20和int 0x21/ah=0x4C退出16位汇编程序之间的区别是什么?,assembly,x86,dos,Assembly,X86,Dos,在不同的时候,我都用过 int 0x20 及 作为结束16位汇编程序的方法 但两者之间的区别是什么 编辑:谢谢大家的评论。根据Alexey对PSP(程序段前缀)的引用,得出 这篇文章似乎暗示,两者之间的区别不仅仅是返回码 很高兴将接受的答案授予任何能够更明确地将两者联系在一起的人。后面的int 0x21允许您指定返回代码 返回码放在寄存器AL中 首先,一些背景知识。DOS使用中断21h进行系统调用。AH用于解复用INT 21h提供的各种功能。当一个程序被执行时,DOS将256个字节放在它前面

在不同的时候,我都用过

int 0x20

作为结束16位汇编程序的方法

但两者之间的区别是什么


编辑:谢谢大家的评论。根据Alexey对PSP(程序段前缀)的引用,得出

这篇文章似乎暗示,两者之间的区别不仅仅是返回码


很高兴将接受的答案授予任何能够更明确地将两者联系在一起的人。

后面的int 0x21允许您指定返回代码

返回码放在寄存器AL中


首先,一些背景知识。DOS使用中断21h进行系统调用。AH用于解复用INT 21h提供的各种功能。当一个程序被执行时,DOS将256个字节放在它前面,称为PSP(程序段前缀),其中包含有关进程的信息

DOS中的原始退出功能是
INT 21/AH=00
。现在,显然DOS开发人员决定从程序返回应该是退出程序的一种方式(这是来自CP/M吗?)
RET
(近)从堆栈中弹出一个单词并跳转到它。因此,当创建一个程序时,它的堆栈以单词
0000
开始。这是PSP的开始。因此,在PSP开始时,有终止程序的代码。为了保持代码小,
int20h
充当
movah,00h的别名;INT 21h

[编辑:这可以在下面的屏幕截图中看到。]

DOS2.0从Unix获得了很多东西,包括返回代码。因此,出现了一个新的int21h函数,
int21h/AH=4ch
,它使用返回代码将其返回到操作系统。此函数还设计用于处理EXE文件(AFAIR在DOS 2.0中也是新的),该文件可以有多个段。先前的退出函数(INT 20h和INT 21h/00)假定CS与COM程序启动时的CS相同,即它指向程序前的PSP 256字节

[编辑:调试”>

历史注释:在CP/M上,有3种退出程序的方法:

  • 调用BDOS函数0(相当于INT 21 AH=00h,DOS函数0)
  • 在0000h跳到WBOOTF位置(相当于PSP偏移000h)
  • 返回
WBOOTF位置由3个字节组成:1个字节用于跳转,2个字节用于跳转目标(BDOS中的WBOOT函数)

在早期版本的CP/M中,调用BDOS函数0或跳转到WBOOT会导致部分CP/M从磁盘重新加载(热启动),并随后运行一些操作系统初始化;同时直接返回到CCP(控制台命令处理器,相当于Command.COM),然后提示输入下一个命令行。AFAIU,CP/m3通常加载到ROM中,并返回到WBOOT位置,导致从ROM重新加载部分操作系统。

这就是我所知道的

MOV AH, 0x4C
INT 0x21
结束正在运行的EXE文件,EXE文件必须以这种方式结束,因为代码段注册为CS。如果我错了,请纠正我,但如果以这种方式结束COM文件,则会得到意外的结果(崩溃、挂起、重新启动等)。因此

INT 0x20
结束一个COM文件

CS和COM程序启动时一样,也就是说,它指向程序前256字节的PSP。(代码段指令指针CS:IP,CS包含代码段)。是的,我们谈论的是寄存器、变量,它们就像一个柜子,我的工作方式就像你能把东西正确地放在抽屉里一样。AX=0000 BX=0000 CX=0000(CX由CL和CH组成)等

我认为COM文件通常限制为64K。第二个原因是COM文件没有数据段,它们有数据,但它与代码驻留在同一段中。我认为它们没有任何段,除了代码,COM文件中的所有数据都存储在64K中。EXE文件有一段,一些EXE文件使用正确的内存型号时可以有更多的段(CS:IP)(请参阅英特尔内存型号)

  • 微小的*
    CS=DS=SS
  • 小型
    DS=SS
  • 中等
    DS=SS
    ,多个代码段
  • 紧凑的单代码段、多数据段
  • 大型多代码段和数据段
  • 庞大的多个代码和数据段;单个数组可能大于64 KB
EXE文件使用小型内存模型的限制为64K。 当使用更大的内存模型和远32位指针时,可以寻址超过64K(仍然有限)。我认为这就是“诀窍”


现在每个人都在抱怨我为什么要使用EXE文件。以上是原因。内存模型来自维基百科。对于那些不在乎的人,我从专业人士那里学到了这一点。Peter Norton和John Socha。来自Norton Utilities(Norton Commander For DOS的幕后策划者)。他有一本关于组装的书,比如““IBM-PC的汇编”。你应该读一下,他解释得最好。他对我来说就像一位好老师。Microsoft CodeView让我明白了很多。在DOS C?Turbo C 2.0中编程是你能得到的最好的。哦,我不再编程了。

这是唯一的区别吗?我注意到在某些环境中(例如,DOSbox,int 0x20工作正常,而int 0x21失控。)定义“失控”“。例如,如果AL中有一个不确定的值,并且后续步骤检查返回代码,则返回非零返回代码的可能性很大。根据惯例,这通常被解释为某种程序失败。@AKE在.COM程序中,您也可以执行
RET
退出(前提是你没有任何东西还没有从堆栈中打开,也没有损坏任何结构。)那
RET
将控制权转移到
int0x20
@AKE:你刚才写的是
mov啊,0x09
?也许你的意思是
mov啊,0x4c
,或者更好
INT 0x20