The Other Three

A previous blog post explored the semi-mysterious yet sometimes highly useful DOS APPEND command. Now it’s time to look at its relatives: ASSIGN, JOIN, and SUBST.

ASSIGN

ASSIGN is the oldest of the bunch. It was written by IBM and first appeared in PC DOS 2.0 in March 1983 (it wasn’t part of MS-DOS 2.x). It is very simple and rather limited.

ASSIGN re-routes requests to an existing drive to another drive. If the user runs

ASSIGN A=C

then requests to drive A: end up addressing drive C: instead.

Note “existing” — the drive letter that is being reassigned must exist. On a machine that has drives A:, B:, C:, and D:, an attempt to run

ASSIGN F=D

will fail with “Invalid parameter”.

Like APPEND, the ASSIGN command is a TSR, and it is one of the earliest DOS TSRs, together with the PRINT command.

ASSIGN works by intercepting INT 25h and 26h vectors (direct disk I/O) and re-routes all accesses according to its internal drive map.

There are no provisions to unload ASSIGN, but running ASSIGN without any arguments will clear its drive mapping table and undo any effects of previous ASSIGN commands.

In later DOS versions,

ASSIGN /STATUS

will show the current drive mappings, if any.

There is a curious interaction between the ASSIGN and APPEND commands (which are both TSRs). For reasons that are not clear, APPEND refuses to install itself if ASSIGN is already installed. However, installing APPEND first and ASSIGN next is not prohibited.

The purpose of the ASSIGN command is very narrow. According to the PC DOS 2.x reference manuals, it was designed to help with applications (presumably written for DOS 1.x) which used hardcoded drive letters. ASSIGN made it possible to make applications that forced the use of floppy drive A: (or perhaps B:) to use the hard disk instead. Hence ASSIGN was a logical addition to PC DOS 2.0.

However, those applications died out a long time ago. In MS-DOS 6.0, ASSIGN was relegated to the “supplemental” tools and was not shipped on the MS-DOS 6.0 floppies.

JOIN

JOIN and SUBST appeared with DOS 3.1 in April 1985. Unlike APPEND and ASSIGN, these two are not TSRs. The mechanism for JOIN and SUBST is built into the DOS kernel and the external utilities only set up the internal DOS state.

JOIN is the DOS equivalent of UNIX mount. It allows a DOS drive to be “joined” to a sub-directory on another drive. Something like this:

JOIN D: C:\MNT

All references to the C:\MNT directory will now be internally re-routed within the DOS kernel to go to drive D: instead.

While the concept of mounting is very familiar to UNIX users, I don’t believe the JOIN command was ever in widespread use in DOS.

The problem with DOS is that it has a fairly draconian limit on pathname length, around 63 characters. And JOIN makes the problem worse, because it inevitably makes every path on the joined drive longer. And users tend to look for ways to make paths shorter, not longer.

It is possible to “unmount” joined drives by running

JOIN D: /D

which makes JOIN fully dynamic.

SUBST

Making paths shorter is exactly what SUBST can do. SUBST is the logical opposite of join, and conceptually similar to UNIX chroot.

SUBST creates a new “virtual” drive letter or changes an existing drive letter such that it is internally mapped to a directory on another drive.

In its most basic use, SUBST is a replacement for ASSIGN. The following command

SUBST A: C:\

will re-route requests to drive A: to go to drive C: instead. Unlike ASSIGN, SUBST can create new drive letters. Note that any virtual drive set up by SUBST must be within the LASTDRIVE limit (that is, DOS must have a CDS available for the drive letter).

Of course SUBST can do much more than ASSIGN, because the target of the new virtual drive can be a directory, not just the root of another drive:

SUBST E: C:\SRC\MYPROJ\FOO

This usage can solve a real problem, which is too long path names. In the above example, references to C:\SRC\MYPROJ\FOO\BAR\FILE.C can instead be shortened as E:\BAR\FILE.C. Such approach is more convenient for users (less reading and typing), and this scheme can work around DOS path length limitations.

Similarly to JOIN, it is possible to remove substituted drives by using the /D switch:

SUBST E: /D

Just like JOIN, SUBST is fully dynamic and substitutions can be created and removed at runtime.

Summary

ASSIGN and APPEND are both TSRs and intercept interrupts 25h/26h (ASSIGN) and 21h (APPEND). ASSIGN was shipped with PC DOS 2.0 and APPEND could theoretically work with DOS 2.x as well. Neither command needs any support from the DOS kernel and both started out as IBM add-ons (with APPEND being initially shipped with the IBM PC Network Program, not DOS).

JOIN and SUBST, on the other hand, are implemented primarily in the DOS kernel. Both appeared in PC DOS 3.1. The external JOIN.EXE and SUBST.EXE utilities are not TSRs and only change internal DOS data. All real work is performed by DOS itself when parsing paths. JOIN and SUBST are conceptually similar to UNIX mount and chroot, respectively.

Legacy

The OS/2 operating system, starting with version 1.0 (1987), shipped all four utilities: APPEND, ASSIGN, JOIN, and SUBST. The catch is that all were DOS programs and only worked in the DOS box. That is also true of OS/2 2.x where all four commands are available, but only work within a single virtual DOS session.

Windows 9x only provided one of these commands, SUBST.

Interestingly, Windows NT shipped with two of the commands, APPEND and SUBST. But there was a big difference: APPEND was still a DOS command, only worked in a single DOS session, and naturally only had any effect on DOS programs. Obviously x64 editions of Windows do not come with APPEND anymore.

SUBST, on the other hand, is a native NT program. One can for example issue

SUBST U: C:\Users\Myaccount

and all Windows applications will see the new virtual drive U: and access the user’s files and directories within C:\Users\Myaccount.

SUBST is thus the only one of the APPEND, ASSIGN, JOIN, SUBST quartet which survived beyond DOS. SUBST is still available in Windows 11 (now 40 years after it was initially introduced in DOS 3.1) and presumably won’t be going anywhere soon.

This entry was posted in DOS, IBM, PC history. Bookmark the permalink.

10 Responses to The Other Three

  1. Oleksandr Diachenko says:

    for pirated DOS games SUBST was a most common command to emulate CD-ROM drive )

  2. David C. says:

    SUBST has one additional benefit. DOS maintains a “current working directory” path for each drive letter. So you could do something like:

    SUBST D: C:\

    And now set different working directories for each:

    CD C:\FOO\BAR
    CD D:\BAZ

    And then perform a sequence of operations using those two paths:

    COPY C:ASDF.TXT D:
    COPY C:ZXCV.TXT D:

    Which means you don’t have to type the full path each time.

  3. Vlad Gnatov says:

    >ASSIGN and APPEND are both TSRs and intercept interrupts 25h/26h (ASSIGN) and 21h (APPEND).

    AFAIR, ASSIGN is also intercepts int 0x21 functions like get/set cur drive, fcb funcs(fcb contains drive), path funcs (may contain drive letter), etc. Very hacky.

    >The external JOIN.EXE and SUBST.EXE utilities are not TSRs and only change internal DOS data.

    The internal DOS data that JOIN/SUBST changes is CDS. In case of SUBST it is done in a pretty clever and minimally intrusive way, see Insert() in ms-dos/v4.0/src/cmd/subst/subst.c

  4. Michal Necasek says:

    Yes, ASSIGN got more complex in DOS 3.0 and takes over INT 21h as well. The original DOS 2.0 ASSIGN definitely did not do that. I’m pretty sure ASSIGN had to do it in DOS 3.x in order to deal with network drives, where there’s no convenient INT 25h/26h to intercept.

  5. Vlad Gnatov says:

    It’s already in PC-DOS 2.0 ASSIGN, perhaps it was not in IBM Network Program:

    PC-DOS 2.0 image from http://old-dos.ru/dl.php?id=3694
    the fragment from assign.com int 0x21 handler:

    han_21: ; seg000:0122
    cmp ah, 0Ch
    jbe short goto_oldint21
    cmp ah, 50h
    jz short goto_oldint21
    cmp ah, 51h
    jz short goto_oldint21
    call sub_102E0
    jz short goto_oldint21
    cmp ah, 4Bh
    jnz short loc_10159
    […]

  6. Michal Necasek says:

    You’re right, it did intercept INT 21h in PC DOS 2.0. Unfortunately I wrote the article a while ago and now I can’t figure out what exactly I was looking at :/

    The original ASSIGN has no INT 2Fh support at all. In fact given how it detects whether ASSIGN is already installed, I wonder if that is exactly why the “APPEND/ASSIGN conflict” is a thing.

    It’s not very pretty, that’s for sure. What I wonder is who even needed ASSIGN for anything in the days of DOS 4.0 or 5.0.

  7. Richard Wells says:

    ASSIGN did help with some software that had to be installed from the A: drive. The PS/2 design made it difficult to make a 5.25″ drive into the A: drive. ASSIGN gets one through that problem if the older software didn’t have a copy protection scheme hostile to ASSIGN.

    Probably a very common situation for DOS 4 and kept on through inertia for DOS 5.

  8. Chris M. says:

    I wouldn’t be surprised if the internal SUBST command in Windows NT shared code with the drive mapping function for network shares. Functionally they do the same thing.

  9. WndSks says:

    Subst might use DefineDosDevice

  10. Ilgaz says:

    I fixed a Epic games problem using this command under Windows 11. It still works.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.