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