我们如何仅通过使用其名称来访问DOS函数,而不使用与之关联的十六进制数?



我正在浏览MS-DOS 1.25源代码MSDOS.ASM,在这里我发现了由这些名称引入的MS-DOS内置函数,如下所示。正如我们所看到的系统标准功能的实现;RENAME";,这个函数是系统调用23,但值23没有被使用。

; Standard Functions
DISPATCH DW ABORT ;0 
DW CONIN 
DW CONOUT 
DW READER 
DW PUNCH 
DW LIST ;5 
DW RAWIO 
DW RAWINP
DW RENAME
RENAME:     ;System call 23 
CALL MOVNAME 
JC ERRET 
ADD SI,5 
MOV DI,OFFSET DOSGROUP:NAME2 
CALL LODNAME 
JC ERRET 
CALL FINDNAME 
JC ERRET 
OR BH,BH ;Check if I/O device name 
JS ERRET ;If so, can't rename it 
MOV SI,OFFSET DOSGROUP:NAME1 
MOV DI,OFFSET DOSGROUP:NAME3 
MOV CX,6
REP MOVSW

我的困惑是系统如何识别RENAME函数,因为同一个函数在不同的模块中可能有不同的名称,并且没有附加十进制或十六进制值。正如我们所看到的,RENAME功能是系统调用23,但代码中没有使用这个值。仅使用RENAME变量名,我们无法访问它的代码。当我看到只有名字用冒号(:(符号的地方时,我很惊讶。就像我发现只有

CONIN:

在某些地方被使用。在这种情况下,期望的代码将如何执行,因为通过只写";CONIN";。我们无法访问欲望代码。

如果您更仔细地查看DISPATCH表,您会发现dw RENAME实际上是它的第23个元素(从零开始计数(。

如果你看一下COMMAND,它是INT 21h向量指向的地方,你会看到它取AH中的值,并将其用作DISPATCH数组的索引,然后调用这个地址:

MOV     BL,AH
MOV     BH,0
SHL     BX,1
;; skip a couple lines
CALL    CS:[BX+DISPATCH]

因此,RENAME是系统调用23,即通过调用AH=23的INT 21h来访问,这一事实被编码在DISPATCH表的布局中。符号RENAME仅在DOS源代码中使用,用户程序不可用。事实上,如果你没有源代码,你就永远不会知道这个标签的名字。

查找表是操作系统调度系统调用的典型方式。否则,您实际需要使用系统调用编号23的唯一方法是,如果您有一长串比较和条件跳转来测试所有可能的系统调用编号,并相应地分支到它们的入口点,这将比查找表效率低得多。

最新更新