问题描述
我正在查看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的唯一方法是,如果您有一长串比较和条件跳转来测试所有可能的系统调用号并相应地分支到它们的入口点,这将比查找效率低得多。桌子。