如何在 16 位汇编程序中 pass/retrieve DOS 命令行参数?

How to pass/retrieve DOS command-line parameters in a 16-bit assembly program?

我正在为 MS-DOS 编写一些小工具。现在我正在写 Shutdown.com,比如 Windows XP 和更高版本。我已经写完了全部代码,现在我只需要从DOS传递参数即可。

我需要传递参数“-r”来重启,传递“-s”来关机。

我该怎么做?

我在 Windows 98 到 link 上使用 TASM(Turbo Assembler 4.1) 并编译。我正在寻找一种非常简单的方法来做到这一点,如果可能的话,仍然是一个 .COM 程序。我看起来和 C 语言的 ARGV 和 ARGC 完全一样,但是对于 16 位汇编...

请记住,我已经知道如何重新启动和如何关闭 PC。
我只需要学习如何将参数从 MS-DOS 命令行传递到我的程序。

根据this site,命令行的长度存储在DS:80h(单字节),实际命令行本身从DS:81h开始。以下是该文章中打印命令行的一些示例代码:

; ----------------------------------------------------------------------------
; echo.asm
;
; Echoes the command line to standard output.  Illustrates DOS system calls
; 40h = write to file, and 4ch = exit process.
;
; Processor: 386 or later
; Assembler: MASM
; OS: DOS 2.0 or later only
; Assemble and link with "ml echo.asm"
; ----------------------------------------------------------------------------

        .model  small
        .stack  64                      ; 64 byte stack
        .386
        .code
start:  movzx   cx,byte ptr ds:[80h]    ; size of parameter string
        mov     ah, 40h                 ; write
        mov     bx, 1                   ; ... to standard output
        mov     dx, 81h                 ; ... the parameter string
        int     21h                     ; ... by calling DOS
        mov     ah, 4ch
        int     21h
        end     start             

没有特定的 API 来检索 MS-DOS 中的命令行。相反,您必须从 Program Segment Prefix (PSP) 的适当偏移量读取值,这是 DOS 用来存储程序特定数据的数据结构。

在偏移量 80h 处,有一个 1 字节的值给出了命令行参数的长度。实际的命令行参数字符串从偏移量 81h 开始,最长可达 127 个字节。根据偏移量80h处的值就知道有多长了,但是也会以回车return(0Dh).

结束

您可以在程序首次执行时使用这些相对于DS寄存器中指针的偏移量。否则,您调用 INT 21h 并将 AH 设置为 62h 以检索指向 BX 寄存器中当前 PSP 的指针。 (函数 62h 需要 DOS 3 或更高版本;在 DOS 2 上,您可以使用未记录的函数 51h)。

Randall Hyde 的 Art of Assembly 的旧 16 位 DOS 版本可在线免费获得(在 HTML and PDF formats). In Chapter 13 中,第 13.3.11 节描述了 PSP,以及以下两节 (13.3.12–13) 解释了如何访问和解析命令行参数,包括示例代码。