我们如何仅通过使用其名称而不使用与之关联的十六进制数字来访问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个元素(从零开始计数)。

如果您查看INT 21h向量指向的COMMAND,您将看到here它将AH中的值用作{{1}中的索引}数组,然后调用此地址:

DISPATCH

因此 MOV BL,AH MOV BH,0 SHL BX,1 ;; skip a couple lines CALL CS:[BX+DISPATCH] 是系统调用23,即通过以AH = 23调用INT 21h进行访问的事实,被编码在RENAME表的布局中。符号DISPATCH仅在DOS源代码本身中使用,并且对用户程序不可用。的确,如果您没有源代码可以查看,那么您根本不会知道该标签的名称。

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