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

god*_*kal 2 assembly operating-system dos x86-16

我正在浏览 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
Run Code Online (Sandbox Code Playgroud)

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

 CONIN:
 
Run Code Online (Sandbox Code Playgroud)

有些地方是用的。在这种情况下,期望代码将如何执行,因为只写“CONIN”。我们无法访问欲望代码。

Nat*_*dge 6

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

如果您查看COMMANDINT 21h 向量指向的位置,您将在此处看到它采用 AH 中的值并将其用作DISPATCH数组的索引,然后调用此地址:

        MOV     BL,AH
        MOV     BH,0
        SHL     BX,1
        ;; skip a couple lines
        CALL    CS:[BX+DISPATCH]
Run Code Online (Sandbox Code Playgroud)

因此,RENAME系统调用 23的事实,即通过调用具有 AH=23 的 INT 21h 来访问,在DISPATCH表的布局中进行了编码。该符号RENAME仅在 DOS 源代码本身中使用,不能用于用户程序。事实上,如果您没有要查看的源代码,您将永远不会知道该标签的名称。

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