DOS int 21 / AH=9 的常量返回值背后的基本原理是什么? 打印字符串中断

问题描述

我在此处查看 DOS int 21h 中断的规范http://spike.scu.edu.au/~barry/interrupts.html

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

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

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

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

解决方法

更多细节:

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

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 不需要被系统调用保留(参见 MS-DOS Programmer's Reference Manual,1.10.4,"Treatment of Registers"),服务 09h 的返回值只是描述为“无”。因此,对于退出时 AL 应包含的内容,没有书面保证;它的内容只是未指定。其他版本的 DOS 可能有不同的行为,因此您显然不应依赖此类行为。

,

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

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

所以虽然我(或 Jester)不能肯定地说这背后没有任何想法,但这个解释很有意义。

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