Assembly DOS int 21/AH=9的恒定返回值背后的原理是什么?(打印字符串中断)

Assembly DOS int 21/AH=9的恒定返回值背后的原理是什么?(打印字符串中断),assembly,x86,dos,x86-16,Assembly,X86,Dos,X86 16,我在这里查看DOSint21h中断的规范 我对汇编不太了解,但似乎AL寄存器是存储中断返回值的标准。例如,服务01h(读取字符)存储在那里读取的字符。服务02h(将字符写入标准输出)将最后一个字符输出存储在那里 但是当涉及到AH=09h(将字符串写入标准输出)时,返回值总是24小时。为什么呢 首先,我认为由于某些技术原因,必须设置一些值,但事实似乎并非如此。有很多DOS服务根本不指定返回值。有些将返回值存储在其他寄存器中,例如2Ch(获取系统时间),它将结果存储在CH、CL、DH和DL寄存器中,

我在这里查看DOS
int21h
中断的规范

我对汇编不太了解,但似乎AL寄存器是存储中断返回值的标准。例如,服务01h(读取字符)存储在那里读取的字符。服务02h(将字符写入标准输出)将最后一个字符输出存储在那里

但是当涉及到AH=09h(将字符串写入标准输出)时,返回值总是24小时。为什么呢

首先,我认为由于某些技术原因,必须设置一些值,但事实似乎并非如此。有很多DOS服务根本不指定返回值。有些将返回值存储在其他寄存器中,例如2Ch(获取系统时间),它将结果存储在CH、CL、DH和DL寄存器中,而不是AL


那么为什么中断服务AH=09h在AL中存储一个值呢?为什么是24小时?

@Jester做了一个很好的观察。24h是$的ascii码,服务09h需要以$结尾的字符串。与服务02h相比,服务02h将最后一个字符打印到输出中,这个字符以AL结尾。现在我们讨论的是一个函数,它打印以$结尾的字符串,并将$保留在AL寄存器中

这个假设还可以解释为什么官方文档没有为中断指定任何返回值。它不是规范的一部分,只是内部工作的结果

所以,虽然我(或杰斯特)不能肯定这背后没有思想,但这个解释很有道理


正如@ecm所指出的那样。这不是“中断09h”。这是“中断21h服务09h”。

只需了解更多细节:

您可以在MS-DOS v1.25中看到此系统调用的源代码:

PRTBUF: ;System call 9
        MOV     SI,DX
OUTSTR:
        LODSB
        CMP     AL,"$"
        JZ      RET20
        CALL    OUT
        JMP     SHORT OUTSTR
它在循环中使用
LODSB
指令从字符串中加载字节,将它们与
$
进行比较,然后写出它们。由于
LODSB
硬连线加载到
AL
,循环在看到
$
时终止,因此
AL
中剩下的就是这个


DOS API规定系统调用不需要保留AX(参见1.10.4“寄存器的处理”),服务09h的返回值仅描述为“无”。因此,对于出口时应包含哪些AL,没有书面保证;它的内容没有具体说明。其他版本的DOS可能会有不同的表现,因此您显然不应该依赖这种行为。

这有点奇怪,对我来说似乎是“偶然的”。。。。i、 也许这就是为什么总是在AL中,当它做了它做的事情,然后返回时发生的事情,所以他们就是这么说的。但是,既然如此,为什么还要说呢?有趣的问题。除非有人在知道中断实现细节的基础上回答,否则这可能会以基于意见的方式结束。@lower是的,好的古老的“基于意见的”:)被过度使用了。尤其是因为这个问题根本不是基于意见的。它有一个明确的答案。也许没有人知道答案,但那是完全不同的事情。“AL=24h(终止字符串的“$”,尽管官方文件声明没有返回任何内容)”@Jester-Oh,但它确实有意义。它是字符串中的最后一个字符,始终是$-terminator@Jester我应该写一个答案,还是你想要这个荣誉?回答“不打断9”的正确位置是在问题的编辑中(我刚才在看到ecm的评论:P之前做的),而不是在答案中。这类评论实际上是在建议改进帖子,而不是回答。@PeterCordes是的,你是对的。我想过,但我想为我的错误辩护,但你当然是对的。