Windows ME's IO.SYS includes HIMEM.SYS, which it loads unconditionally. Since it is possible to decompress and disassemble IO.SYS, and hack it to enable full dos mode, can we go a step further and modify it to not to load the built-in himem.sys automatically?

Some info on decompressing and disassembling IO.SYS can be found here: Disassembling Windows IO.SYS

  • You might want to register your account, so you can log in again later. Otherwise, if your browser loses your login cookies, you won't be able to edit your own question and stuff like that.
    – wizzwizz4
    Apr 20 at 15:00
  • 1
    I've edited your question a bit. If you don't like my edits, you can roll them back, or click edit to make further changes. Also, I found an MSFN thread where some people were discussing this kind of thing (removing unused code from io.sys).
    – wizzwizz4
    Apr 20 at 15:11
  • The built-in XMS driver seems relatively easy to disable by patching three bytes, but… why would you want to? All it gets you is a crippled DOS. Apr 20 at 16:59
  • I want to have an option at startup to run a pure dos without any memory managers. Rarely needed but useful feature. Which three bytes ? Can I load himem.sys from config.sys after that?
    – Kore
    Apr 20 at 17:28
  • someone actually uses Win ME ? As I remember it was unstable and unusable on every machine I encounter back in the days ... did they patch it? to point it was usable ?
    – Spektre
    Apr 21 at 6:21

1 Answer 1


That the IO.SYS of Windows Me includes an integrated HIMEM.SYS is something of a simplification. What is true is that IO.SYS includes a built-in XMS driver; but even if it was derived from code originally written for HIMEM.SYS, it cannot really be considered a discrete unit any more. Other code in the DOS kernel assumes it is present and working, and will fail if that assumption is broken. It is arguably simply just another integral part of the DOS kernel.

Still, it’s relatively easy to disable that built-in driver. Assuming you have uncompressed the file, it’s enough to patch three bytes:

--- original
+++ patched
@@ -117,7 +117,7 @@
 000008a0  b8 00 70 00 c0 a0 62 02  8c 02 4c 50 54 33 20 20  |..p...b...LPT3  |
 000008b0  20 20 01 ea 00 00 00 00  ca 00 70 00 00 80 62 02  |  ........p...b.|
 000008c0  99 02 43 4f 4d 32 20 20  20 20 dc 00 70 00 00 80  |..COM2    ..p...|
-000008d0  62 02 9f 02 43 4f 4d 33  20 20 20 20[50 04]70 00  |b...COM3    P.p.|
+000008d0  62 02 9f 02 43 4f 4d 33  20 20 20 20[ff ff]70 00  |b...COM3    ..p.|
 000008e0  00 80 62 02 a5 02 43 4f  4d 34 20 20 20 20 e8 ba  |..b...COM4    ..|
 000008f0  01 f2 07 e8 b5 01 b2 0c  85 03 18 12 00 00 00 00  |................|
 00000900  10 00 00 00 00 13 00 00  00 00 15 00 00 00 00 19  |................|
@@ -6567,7 +6567,7 @@
 0001ee20  e8 0a 66 c1 ea 0a e8 66  00 66 0b db 75 9c 66 83  |..f....f.f..u.f.|
 0001ee30  3e c5 00 01 07 c3 1e 06  1f 8b 0e fa 34 8b 1e fc  |>...........4...|
 0001ee40  34 66 33 c0 c6 07 04 88  47 01 66 89 47 02 66 89  |4f3.....G.f.G.f.|
-0001ee50  47 06 83 c3 0a e2 ed 89  1e 00 35 1f c3[1e]66 50  |G.........5...fP|
+0001ee50  47 06 83 c3 0a e2 ed 89  1e 00 35 1f c3[cb]66 50  |G.........5...fP|
 0001ee60  66 b8 00 00 ff ff 8e d8  b8 04 32 66 87 06 bc 00  |f.........2f....|
 0001ee70  66 26 a3 fc 31 66 b8 8d  32 ff ff 66 87 06 54 00  |f&..1f..2..f..T.|
 0001ee80  66 26 a3 f8 31 b8 ff ff  e8 a0 00 66 58 1f cb 66  |f&..1......fX..f|

The particular offsets where those bytes are found may differ (depending on the version of IO.SYS you have), but the surrounding data should be pretty much exactly the same. What this does is:

  • It disconnects the XMSXXXX0 character device header from the linked list of built-in drivers;
  • It disables hooking interrupt vectors 0x2f and 0x15 that would otherwise allow accessing XMS driver services.

The XMS driver code still occupies conventional memory, but is completely inert, and will not be found by software looking for it. A virtual machine booted from an Emergency Boot Disk floppy image with such a modified IO.SYS superficially seems relatively stable, with the MEM command behaving as if no XMS driver were present. And by ‘relatively stable’, I mean that if the CONFIG.SYS file contains both DOS=HIGH,UMB and loads the DISPLAY.SYS device driver, the system hangs at boot. Clearly there is some code somewhere else within that version of DOS that blindly assumes that the XMS driver is always present and enabled. And why would it not? Until now, it indeed was. (Attempting to launch the VMM32, i.e. the graphical, protected-mode part of Windows Me under this modified kernel also fails, and not especially gracefully, but that was probably to be expected.)

So to keep the system working robustly (as much as DOS can be robust), you would probably need to also insert some code to account for the possibility that the XMS driver is missing. But to me, that starts to seem like adding functionality instead of removing it. It makes the kernel less stable, and it doesn’t even gain you anything to do this, other than being able to scrub the now non-functional code with zeroes, so that the kernel may compress better (and even that is only on-disk).

To fully excise the XMS driver from the DOS kernel and reclaim its memory, you would have to perform a complete disassembly of the whole kernel, remove the XMS code, and then assemble it back (while fixing surrounding code to no longer unconditionally assume its existence). This is not an insurmountable task, but a pretty laborious one, so I would not find it particularly appealing in light of alternative solutions: to simply downgrade to MS-DOS 7.10, or to switch to another DOS kernel, which allows you to use any XMS driver you wish, including none.

  • Is there a way to prevent loading of the xms code completely and would that allow for loading himem.sys manually from config.sys file? My goal is to add a clean dos mode but not at the cost of crippled xms functionality.
    – Kore
    Apr 20 at 20:57
  • 1
    Start an annotated disassembly project, correctly identify all in-code offsets, and then excise the XMS driver and XMS-dependent code from it. But honestly, you’d be better off just running another DOS than creating your own Frankenstein version. Apr 20 at 21:23
  • Ok, understood. I appreciate your expertise. Couldn’t find any solutions to the problem and now I know why.
    – Kore
    Apr 20 at 22:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.