Recent from talks
Nothing was collected or created yet.
Conventional memory
View on Wikipedia
This article needs additional citations for verification. (November 2025) |

In DOS memory management, conventional memory, also called base memory, is the first 640 kilobytes of the memory on IBM PC or compatible systems. It is the read-write memory directly addressable by the processor for use by the operating system and application programs. As memory prices rapidly declined, this design decision became a limitation in the use of large memory capacities until the introduction of operating systems and processors that made it irrelevant.
640 KB barrier
[edit]| 0-block | 1st 64 KB | Ordinary user memory to 64 KB (low memory area) |
| 1-block | 2nd 64 KB | Ordinary user memory to 128 KB |
| 2-block | 3rd 64 KB | Ordinary user memory to 192 KB |
| 3-block | 4th 64 KB | Ordinary user memory to 256 KB |
| 4-block | 5th 64 KB | Ordinary user memory to 320 KB |
| 5-block | 6th 64 KB | Ordinary user memory to 384 KB |
| 6-block | 7th 64 KB | Ordinary user memory to 448 KB |
| 7-block | 8th 64 KB | Ordinary user memory to 512 KB |
| 8-block | 9th 64 KB | Ordinary user memory to 576 KB |
| 9-block | 10th 64 KB | Ordinary user memory to 640 KB |
| A-block | 11th 64 KB | Extended video memory (EGA) |
| B-block | 12th 64 KB | Standard video memory (MDA/CGA) |
| C-block | 13th 64 KB | ROM expansion (XT, EGA, 3270 PC) |
| D-block | 14th 64 KB | other use (PCjr cartridges, LIM EMS) |
| E-block | 15th 64 KB | other use (PCjr cartridges, LIM EMS) |
| F-block | 16th 64 KB | System ROM-BIOS and ROM-BASIC |
The 640 KB barrier is an architectural limitation of IBM PC compatible PCs. The Intel 8088 CPU, used in the original IBM PC, was able to address 1 MB (220 bytes), since the chip offered 20 address lines. In the design of the PC, the memory below 640 KB was for random-access memory on the motherboard or on expansion boards, and it was called the conventional memory area. The first memory segment (64 KB) of the conventional memory area is named lower memory or low memory area. The remaining 384 KB beyond the conventional memory area, called the upper memory area (UMA), was reserved for system use and optional devices. UMA was used for the ROM BIOS, additional read-only memory, BIOS extensions for fixed disk drives and video adapters, video adapter memory, and other memory-mapped input and output devices. The design of the original IBM PC placed the Color Graphics Adapter (CGA) memory map in UMA.
The need for more RAM grew faster than the needs of hardware to utilize the reserved addresses, which resulted in RAM eventually being mapped into these unused upper areas to utilize all available addressable space. This introduced a reserved "hole" (or several holes) into the set of addresses occupied by hardware that could be used for arbitrary data. Avoiding such a hole was difficult and ugly and not supported by DOS or most programs that could run on it. Later, space between the holes would be used as upper memory blocks (UMBs).
To maintain compatibility with older operating systems and applications, the 640 KB barrier remained part of the PC design even after the 8086/8088 had been replaced with the Intel 80286 processor, which could address up to 16 MB of memory in protected mode. The 1 MB barrier also remained as long as the 286 was running in real mode, since DOS required real mode which uses the segment and offset registers in an overlapped manner such that addresses with more than 20 bits are not possible. It is still present in IBM PC compatibles today if they are running in real mode such as used by DOS. Even the most modern Intel PCs still have the area between 640 and 1024 KB reserved.[3][4] This however is invisible to programs (or even most of the operating system) on newer operating systems (such as Windows, Linux, or Mac OS X) that use virtual memory, because they have no awareness of physical memory addresses at all. Instead they operate within a virtual address space, which is defined independently of available RAM addresses.[5]
Some motherboards feature a "Memory Hole at 15 Megabytes" option required for certain VGA video cards that require exclusive access to one particular megabyte for video memory. Later video cards using the AGP (PCI memory space) bus can have 256 MB memory with 1 GB aperture size.
Additional memory
[edit]One technique used on early IBM XT computers was to install additional RAM into the video memory address range and push the limit up to the start of the Monochrome Display Adapter (MDA). Sometimes software or a custom address decoder was required for this to work. This moved the barrier to 704 KB (with MDA/HGC) or 736 KB (with CGA).[6][7]
Memory managers on 386-based systems (such as QEMM or MEMMAX (+V) in DR-DOS) could achieve the same effect, adding conventional memory at 640 KB and moving the barrier to 704 KB (up to segment B000, the start of MDA/HGC) or 736 KB (up to segment B800, the start of the CGA).[7] Only CGA could be used in this situation, because Enhanced Graphics Adapter (EGA) video memory was immediately adjacent to the conventional memory area below the 640 KB line; the same memory area could not be used both for the frame buffer of the video card and for transient programs.
All Computers' piggy-back add-on memory management units AllCard for XT-[8][9] and Chargecard[10] for 286/386SX-class computers, as well as MicroWay's ECM (Extended Conventional Memory) add-on-board[11] allowed normal memory to be mapped into the A0000–EFFFF (hex) address range, giving up to 952 KB for DOS programs. Programs such as Lotus 1-2-3, which accessed video memory directly, needed to be patched to handle this memory layout. Therefore, the 640 KB barrier was removed at the cost of hardware compatibility.[10]
It was also possible to use console redirection[12] (either by specifying an alternative console device like AUX: when initially invoking COMMAND.COM or by using CTTY later on) to direct output to and receive input from a dumb terminal or another computer running a terminal emulator. Assuming the System BIOS still permitted the machine to boot (which is often the case at least with BIOSes for embedded PCs), the video card in a so called headless computer could then be removed completely, and the system could provide a total of 960 KB of continuous DOS memory for programs to load.
Similar usage was possible on many DOS- but not IBM-compatible computers with a non-fragmented memory layout, for example SCP S-100 bus systems equipped with their 8086 CPU card CP-200B and up to sixteen SCP 110A memory cards (with 64 KB RAM on each of them) for a total of up to 1024 KB (without video card, but utilizing console redirection, and after mapping out the boot/BIOS ROM),[13] the Victor 9000/Sirius 1 which supported up to 896 KB, or the Apricot PC with more continuous DOS memory to be used under its custom version of MS-DOS.
DOS driver software and TSRs
[edit]Most standard programs written for DOS did not necessarily need 640 KB or more of memory. Instead, driver software and utilities referred to as terminate-and-stay-resident programs (TSRs) could be used in addition to the standard DOS software. These drivers and utilities typically used some conventional memory permanently, reducing the total available for standard DOS programs.
Some very common DOS drivers and TSRs using conventional memory included:
- ANSI.SYS - support for color text and different text resolutions
- ASPIxDOS.SYS, ASPIDISK.SYS, ASPICD.SYS - all must be loaded for Adaptec SCSI drives and CDROMs to work
- DOSKEY.EXE - permits recall of previously typed DOS commands using up-arrow
- LSL.EXE, E100BODI.EXE (or other network driver), IPXODI.EXE, NETX.EXE - all must be loaded for NetWare file server drive letter access
- MOUSE.EXE - support for mouse devices in DOS programs
- MSCDEX.EXE - support for CDROM drive access and drive letter, used in combination with a separate manufacturer-specific driver. Needed in addition to above SCSI drivers for access to a SCSI CDROM device.
- SBCONFIG.EXE - support for Sound Blaster 16 audio device; a differently-named driver was used for various other sound cards, also occupying conventional memory.
- SMARTDRV.EXE - install drive cache to speed up disk reads and writes; although it could allocate several megabytes of memory beyond 640 KB for the drive caching, it still needed a small portion of conventional memory to function.
As can be seen above, many of these drivers and TSRs could be considered practically essential to the full-featured operation of the system. But in many cases a choice had to be made by the computer user, to decide whether to be able to run certain standard DOS programs or have all their favorite drivers and TSRs loaded. Loading the entire list shown above is likely either impractical or impossible, if the user also wants to run a standard DOS program as well.
In some cases drivers or TSRs would have to be unloaded from memory to run certain programs, and then reloaded after running the program. For drivers that could not be unloaded, later versions of DOS included a startup menu capability to allow the computer user to select various groups of drivers and TSRs to load before running certain high-memory-usage standard DOS programs.
Upper memory blocks and loading high
[edit]As DOS applications grew larger and more complex in the late 1980s and early 1990s, it became common practice to free up conventional memory by moving the device drivers and TSR programs into upper memory blocks (UMBs) in the upper memory area (UMA) at boot, in order to maximize the conventional memory available for applications. This had the advantage of not requiring hardware changes, and preserved application compatibility.
This feature was first provided by third-party products such as QEMM, before being built into DR DOS 5.0 in 1990 then MS-DOS 5.0 in 1991. Most users used the accompanying EMM386 driver provided in MS-DOS 5, but third-party products from companies such as QEMM also proved popular.
At startup, drivers could be loaded high using the "DEVICEHIGH=" directive, while TSRs could be loaded high using the "LOADHIGH", "LH" or "HILOAD" directives. If the operation failed, the driver or TSR would automatically load into the regular conventional memory instead.
CONFIG.SYS, loading ANSI.SYS into UMBs, no EMS support enabled:
DEVICE=C:\DOS\HIMEM.SYS DEVICE=C:\DOS\EMM386.EXE NOEMS DEVICEHIGH=C:\DOS\ANSI.SYS
AUTOEXEC.BAT, loading MOUSE, DOSKEY, and SMARTDRV into UMBs if possible:
LH C:\DOS\MOUSE.EXE LH C:\DOS\DOSKEY.EXE LH C:\DOS\SMARTDRV.EXE
The ability of DOS versions 5.0 and later to move their own system core code into the high memory area (HMA) through the DOS=HIGH command gave another boost to free memory.
Driver and TSR optimization
[edit]Hardware expansion boards could use any of the upper memory area for ROM addressing, so the upper memory blocks were of variable size and in different locations for each computer, depending on the hardware installed. Some windows of upper memory could be large and others small. Loading drivers and TSRs high would pick a block and try to fit the program into it, until a block was found where it fit, or it would go into conventional memory.
An unusual aspect of drivers and TSRs is that they would use different amounts of conventional and/or upper memory, based on the order they were loaded. This could be used to advantage if the programs were repeatedly loaded in different orders, and checking to see how much memory was free after each permutation. For example, if there was a 50 KB UMB and a 10 KB UMB, and programs needing 8 KB and 45 KB were loaded, the 8 KB might go into the 50 KB UMB, preventing the second from loading. Later versions of DOS allowed the use of a specific load address for a driver or TSR, to fit drivers/TSRs more tightly together.
In MS-DOS 6.0, Microsoft introduced MEMMAKER, which automated this process of block matching, matching the functionality third-party memory managers offered. This automatic optimization often still did not provide the same result as doing it by hand, in the sense of providing the greatest free conventional memory.
Also in some cases third-party companies wrote special multi-function drivers that would combine the capabilities of several standard DOS drivers and TSRs into a single very compact program that used just a few kilobytes of memory. For example, the functions of mouse driver, CD-ROM driver, ANSI support, DOSKEY command recall, and disk caching would all be combined together in one program, consuming just 1 – 2 kilobytes of conventional memory for normal driver/interrupt access, and storing the rest of the multi-function program code in EMS or XMS memory.
DOS extenders
[edit]The barrier was only overcome with the arrival of DOS extenders, which allowed DOS applications to run in 16-bit or 32-bit protected mode, but these were not very widely used outside of computer gaming. With a 32-bit DOS extender, a game could benefit from a 32-bit flat address space and the full 32-bit instruction set without the 66h/67h operand/address override prefixes. 32-bit DOS extenders required compiler support (32-bit compilers) while XMS and EMS worked with an old compiler targeting 16-bit real-mode DOS applications. The two most common specifications for DOS extenders were VCPI- and later DPMI-compatible with Windows 3.x.
The most notable DPMI-compliant DOS extender may be DOS/4GW, shipping with Watcom. It was very common in games for DOS. Such a game would consist of either a DOS/4GW 32-bit kernel, or a stub which loaded a DOS/4GW kernel located in the path or in the same directory and a 32-bit "linear executable". Utilities are available which can strip DOS/4GW out of such a program and allow the user to experiment with any of the several, and perhaps improved, DOS/4GW clones.
Prior to DOS extenders, if a user installed additional memory and wished to use it under DOS, they would first have to install and configure drivers to support either expanded memory specification (EMS) or extended memory specification (XMS) and run programs supporting one of these specifications.
EMS was a specification available on all PCs, including those based on the Intel 8086 and Intel 8088, which allowed add-on hardware to page small chunks of memory in and out (bank switching) of the "real mode" addressing space (0x0400–0xFFFF). This allowed 16-bit real-mode DOS programs to access several megabytes of RAM through a hole in real memory, typically (0xE000–0xEFFF). A program would then have to explicitly request the page to be accessed before using it. These memory locations could then be used arbitrarily until replaced by another page. This is very similar to modern paged virtual memory. However, in a virtual memory system, the operating system handles all paging operations, while paging was explicit with EMS.
XMS provided a basic protocol which allowed a 16-bit DOS programs to load chunks of 80286 or 80386 extended memory in low memory (address 0x0400–0xFFFF). A typical XMS driver had to switch to protected mode in order to load this memory. The problem with this approach is that while in 286 protected mode, direct DOS calls could not be made. The workaround was to implement a callback mechanism, requiring a reset of the 286. On the 286, this was a major problem. The Intel 80386, which introduced "virtual 8086 mode", allowed the guest kernel to emulate the 8086 and run the host operating system without having to actually force the processor back into "real mode". HIMEM.SYS 2.03 and higher used unreal mode on the 80386 and higher CPUs while HIMEM.SYS 2.06 and higher used LOADALL to change undocumented internal registers on the 80286, significantly improving interrupt latency by avoiding repeated real mode/protected mode switches.[14]
Windows installs its own version of HIMEM.SYS[15] on DOS 3.3 and higher. Windows HIMEM.SYS launches 32-bit protected mode XMS (n).0 services provider for the Windows Virtual Machine Manager, which then provides XMS (n-1).0 services to DOS boxes and the 16-bit Windows machine (e.g. DOS 7 HIMEM.SYS is XMS 3.0 but running 'MEM' command in a Windows 95 DOS window shows XMS 2.0 information).
See also
[edit]- Expanded memory (EMS)
- Extended memory (XMS)
- High memory area (HMA)
- DOS Protected Mode Services (DPMS)
- LOADHIGH
- Long mode
- RAM limit
- Transient Program Area (TPA)
- Upper memory area (UMA)
- x86 memory segmentation
- 3 GB barrier
References
[edit]- ^ Norton, Peter (1986). Inside the IBM PC, Revised and Enlarged, Brady. ISBN 0-89303-583-1, p. 108.
- ^ U.S. patent 4,926,322 - Software emulation of bank-switched memory using a virtual DOS monitor and paged memory management, Fig. 1
- ^ Yao, Jiewen; Zimmer, Vincent J. (February 2015). "White Paper: A Tour beyond BIOS Memory Map Design in UEFI BIOS" (PDF). Intel Corporation. Archived from the original (PDF) on 2015-09-30. Retrieved 2016-08-25.
- ^ Russinovich, Mark Eugene; Solomon, David A.; Ionescu, Alex (2012). Windows Internals. Vol. Part 2 (6th ed.). Microsoft Press. p. 322.
Note the gap in the memory address range from page 9F000 to page 100000...
- ^ Richter, Jeffrey. Programming Applications for Microsoft Windows. pp. 435 ff.
- ^ Atkinson, Cy (2001). "What is High Memory, why do i care, and how can I use it?". San Jose, CA, USA. Archived from the original on 2016-03-03. Retrieved 2017-03-13.
- ^ a b Paul, Matthias R. (1997-07-30). NWDOS-TIPs — Tips & Tricks rund um Novell DOS 7, mit Blick auf undokumentierte Details, Bugs und Workarounds [NWDOSTIPs — Tips & tricks for Novell DOS 7, with special focus on undocumented details, bugs and workarounds]. MPDOSTIP (in German) (3 ed.). Archived from the original on 2016-06-06. Retrieved 2016-06-06. (NB. NWDOSTIP.TXT is a comprehensive work on Novell DOS 7 and OpenDOS 7.01, including the description of many undocumented features and internals. It is part of the author's yet larger MPDOSTIP.ZIP collection maintained up to 2001 and distributed on many sites at the time. The provided link points to a HTML-converted older version of the NWDOSTIP.TXT file.)
- ^ Petzold, Charles (1986). "More Options For Enlarging the Dimensions of Memory". PC Magazine. Vol. 5, no. 11. ISSN 0888-8507.
- ^ "AllCard review". Personal Computer World. September 1986. p. 138.
- ^ a b Zerbe, Klaus (November 1987). Burgwitz, Andreas (ed.). "Speicher-Kredit - All Chargecard für ATs". c't - magazin für computertechnik. Prüfstand (in German). Vol. 1987, no. 11. Verlag Heinz Heise GmbH & Co. KG. pp. 58, 60. ISSN 0724-8679.
- ^ Petzold, Charles (1986-09-16). "Number Smasher/ECM". PC Magazine. Accelerator Boards. Vol. 5, no. 15. pp. 148, 150. ISSN 0888-8507. Archived from the original on 2020-03-03. Retrieved 2020-03-03.
- ^ Kontron User's Guide - COMe-cBTi6R. Document Revision 1.0. Kontron. 2021. pp. 37, 60, 64. Archived from the original on 2023-09-23. Retrieved 2023-09-23. (89 pages)
- ^ Paterson, Tim (2007-11-24). "The First DOS Machine". DosMan Drivel. Archived from the original on 2021-09-18. Retrieved 2021-12-23.
IBM also reintroduced memory limitations that I had specifically avoided in designing the 8086 CPU [card]. For S-100 computers, a low-cost alternative to using a regular computer terminal was to use a video card. The video card, however, used up some of the memory address space. The boot ROM would normally use up address space as well. SCP systems were designed to be used with a terminal, and the boot ROM could be disabled after boot-up. This made the entire 1 MB of memory address space available for RAM. IBM, on the other hand, had limited the address space in their PC to 640 KB of RAM due to video and boot/BIOS ROM. This limitation has been called the "DOS 640K barrier", but it had nothing to do with DOS. Microsoft took full advantage of the SCP system capability. In 1988, years after SCP had shut down, they were still using the SCP system for one task only it could perform ("linking the linker"). Their machine was equipped with the full 1 MB of RAM – 16 of the 64 KB cards. That machine could not be retired until 32-bit software tools were developed for Intel's 386 microprocessor.
- ^ "HIMEM.SYS, unreal mode, and LOADALL". OS/2 Museum.
- ^ "Overview of Memory-Management Functionality in MS-DOS". Microsoft Support. 2003-05-12. Archived from the original on 2007-02-12. Retrieved 2012-08-13.
Further reading
[edit]- Brenner, Rudolf (1986). "Mehr als 640 K in PCs". c't - magazin für computertechnik (in German). Vol. 1986, no. 11. Verlag Heinz Heise GmbH & Co. KG. p. 94. ISSN 0724-8679.
- Landenberger, Andreas (November 1987). Wilde, Michael (ed.). "Booten mit List - PC-Speicher über 640 KB voll genutzt". c't - magazin für computertechnik. Praxistip (in German). Vol. 1987, no. 11. Verlag Heinz Heise GmbH & Co. KG. pp. 154, 156. ISSN 0724-8679.
Conventional memory
View on GrokipediaDefinition and Historical Context
Core Definition
Conventional memory refers to the first 640 kilobytes (KB) of system random access memory (RAM) in IBM PC-compatible systems running MS-DOS, spanning the address range from 0x00000 to 0x9FFFF. This portion is directly addressable by the operating system in real mode without requiring special memory management techniques or hardware expansions.[4][5] In MS-DOS environments, conventional memory serves as the primary workspace for executing applications, the command interpreter (COMMAND.COM), and terminate-and-stay-resident (TSR) programs. It provides the foundational space where the operating system loads device drivers, allocates buffers, and runs user programs, with the remainder after system reservations available for software operations. The Intel 8088 processor's 16-bit addressing in real mode, combined with 20-bit physical addressing via segment:offset notation, limits the total accessible address space to 1 megabyte (MB), of which conventional memory occupies the lower 640 KB.[4][6][5] This memory type is distinct from extended memory, which resides above 1 MB and requires protected-mode support on 80286 or higher processors for access, and from expanded memory, which follows the Expanded Memory Specification (EMS) standard and uses dedicated page frames within the 1 MB address space for swapping larger amounts of data. The upper memory area, a fragmented 384 KB region above conventional memory up to 1 MB, is generally reserved for hardware adapters and system ROM, making it unavailable for standard DOS use without reconfiguration.[4][6]Origins in Early PC Architecture
The IBM Personal Computer (PC), introduced in August 1981, was built around the Intel 8088 microprocessor, a 16-bit processor operating in real mode with a 20-bit address bus that limited the total addressable memory to 1 MB.[7] This design choice reflected the era's hardware constraints and anticipated needs for personal computing, where the system board provided base RAM expandable from 16 KB to 256 KB, with further expansion possible via slots.[7] The 8088's segmented addressing scheme, using segment registers to form physical addresses up to 1 MB, became the foundational architecture for compatible systems.[7] Early allocation decisions in the IBM PC reserved significant portions of the 1 MB address space for hardware-specific functions, leaving 640 KB (from 00000h to 9FFFFh) available for user programs and the operating system, known as conventional memory.[7] The upper memory area included 128 KB for video memory (A0000h to BFFFFh), supporting monochrome or color/graphics adapters, 64 KB for the BIOS ROM (F0000h to FFFFFh) containing system firmware and startup routines, and additional space for adapter ROMs (e.g., C8000h to EFFFFh in 2 KB increments identified by a 55AAh signature).[7] These reservations prioritized compatibility with peripherals and display standards, such as the MDA or CGA, over maximizing user-accessible RAM.[7] The memory configuration evolved with the IBM PC/XT in 1983, which retained the original 1 MB address space and 640 KB conventional memory limit while adding a built-in hard disk and supporting up to 640 KB total RAM through modular expansions.[8] Standardization of the memory map ensured software compatibility across models, with the same allocations for BIOS, video, and adapters.[8] By 1984, the IBM PC/AT introduced the Intel 80286 processor, enabling up to 16 MB of RAM, yet it preserved the 640 KB conventional memory boundary within the first 1 MB for backward compatibility with existing applications and the DOS ecosystem.[2] MS-DOS 1.0, released concurrently with the IBM PC in 1981, was specifically designed to operate within this 640 KB conventional memory constraint, loading into the low 64 KB and supporting applications up to the full 640 KB while respecting hardware reservations.[9] This architecture profoundly influenced software development practices throughout the 1980s and early 1990s, as developers optimized code for the limit until Windows 95 in 1995, which finally enabled broader 32-bit memory access while maintaining DOS compatibility modes.[9]Memory Layout and the 640 KB Limit
Overall DOS Memory Map
The first megabyte (1 MB) of physical memory in IBM PC-compatible systems running MS-DOS is segmented into distinct regions to accommodate the operating system, applications, and hardware-mapped devices. This layout, dictated by the 20-bit address bus of the Intel 8086/8088 processors, spans addresses from 0x00000 to 0xFFFFF and forms the foundation of DOS memory management. The lower portion, known as conventional memory, provides the primary workspace for software, while the upper portion is largely reserved for system hardware, creating natural boundaries and potential gaps for optimization.[10] In the lowest addresses, the Interrupt Vector Table (IVT) occupies the first 1 KB (0x00000–0x003FF), storing 256 four-byte pointers to interrupt service routines for hardware events and software traps. Immediately following is the BIOS Data Area (BDA) at 0x00400–0x004FF (256 bytes), which holds system configuration data such as equipment lists, timer counts, and disk parameters maintained by the BIOS. The remainder of conventional memory, from roughly 0x00500 to 0x9FFFF (totaling 640 KB), serves as the allocatable space for the DOS kernel, device drivers, the command interpreter, and user programs. During the boot process, core DOS components like IO.SYS and MSDOS.SYS load into low conventional memory, followed by items from CONFIG.SYS and AUTOEXEC.BAT; the command interpreter COMMAND.COM then loads near the top of this region, typically occupying about 50–60 KB and leaving the bulk available for applications and terminate-and-stay-resident (TSR) programs.[10][11] The upper memory area (UMA) begins at 0xA0000 (640 KB) and extends to 0xFFFFF (1 MB total), comprising 384 KB primarily reserved for memory-mapped hardware. Video memory is allocated here at 0xA0000–0xBFFFF (128 KB), with subranges for color text (0xB8000–0xBFFFF, 32 KB) or monochrome text (0xB0000–0xB7FFF, 32 KB) and graphics modes (0xA0000–0xAFFFF, 64 KB), depending on the display adapter in use. From 0xC0000 onward, ROM code and expansion card firmware occupy segments, including the video BIOS at 0xC0000–0xC7FFF (32 KB), optional adapter ROMs in 0xC8000–0xDFFFF (96 KB) and 0xE0000–0xEFFFF (64 KB), and the system BIOS at 0xF0000–0xFFFFF (64 KB), which contains startup routines and low-level services. These fixed reservations create intermittent "holes" in the UMA—unused RAM segments between hardware areas—that can be exploited as upper memory blocks (UMBs) for loading small drivers or TSRs. An extended BIOS data area (EBDA) may also appear near the top of conventional memory (e.g., 0x9FC00–0x9FFFF) on systems with more than 64 KB of base RAM.[10][12][1] The following textual diagram illustrates the typical segmentation (addresses in hexadecimal; sizes approximate and hardware-dependent):Address Range Size Description
0x00000–0x003FF 1 KB Interrupt Vector Table (IVT)
0x00400–0x004FF 256 B BIOS Data Area (BDA)
0x00500–0x9FBFF ~639 KB Conventional Memory (DOS kernel, [COMMAND.COM](/page/COMMAND.COM), drivers, applications, TSRs; exact free space varies)
0x9FC00–0x9FFFF ~1 KB Extended BIOS Data Area (EBDA, if present)
0xA0000–0xBFFFF 128 KB Video Memory (text/graphics buffers)
0xC0000–0xC7FFF 32 KB Video [BIOS](/page/BIOS) ROM
0xC8000–0xDFFFF 96 KB [Expansion Card](/page/Expansion_card) ROMs/Adapter [Firmware](/page/Firmware) (optional)
0xE0000–0xEFFFF 64 KB [Expansion Card](/page/Expansion_card) ROMs/Adapter [Firmware](/page/Firmware) (optional)
0xF0000–0xFFFFF 64 KB System [BIOS](/page/BIOS) ROM
Address Range Size Description
0x00000–0x003FF 1 KB Interrupt Vector Table (IVT)
0x00400–0x004FF 256 B BIOS Data Area (BDA)
0x00500–0x9FBFF ~639 KB Conventional Memory (DOS kernel, [COMMAND.COM](/page/COMMAND.COM), drivers, applications, TSRs; exact free space varies)
0x9FC00–0x9FFFF ~1 KB Extended BIOS Data Area (EBDA, if present)
0xA0000–0xBFFFF 128 KB Video Memory (text/graphics buffers)
0xC0000–0xC7FFF 32 KB Video [BIOS](/page/BIOS) ROM
0xC8000–0xDFFFF 96 KB [Expansion Card](/page/Expansion_card) ROMs/Adapter [Firmware](/page/Firmware) (optional)
0xE0000–0xEFFFF 64 KB [Expansion Card](/page/Expansion_card) ROMs/Adapter [Firmware](/page/Firmware) (optional)
0xF0000–0xFFFFF 64 KB System [BIOS](/page/BIOS) ROM
Causes of the 640 KB Barrier
The 640 KB barrier in conventional memory stemmed primarily from hardware constraints imposed by the Intel 8088 microprocessor used in the original IBM PC. The 8088 featured a 20-bit address bus, enabling it to address up to 1 MB (2^20 bytes) of total memory in real mode, but this space had to be shared among RAM, peripherals, and system firmware.[13] IBM's architecture further subdivided this 1 MB address space, reserving significant portions above 640 KB for essential hardware functions, which fixed the limit for user-accessible RAM. Specifically, addresses from 0xA0000 to 0xBFFFF (128 KB) were allocated to video memory for monochrome and color/graphics adapters, while 0xF0000 to 0xFFFFF (64 KB) housed the BIOS ROM containing system initialization and I/O routines. Additional areas, such as 0xC0000 to 0xEFFFF (192 KB), were set aside for memory-mapped I/O expansion and optional ROMs on adapter cards, ensuring compatibility with fixed peripherals without interfering with user programs. This design choice in the 1981 IBM PC technical specifications balanced expandability with hardware stability, preventing the operating system from directly accessing upper regions to avoid conflicts with device mappings.[1] Software compatibility reinforced the barrier, as MS-DOS was engineered to load its kernel into low memory starting just after the interrupt vector table and BIOS data area (typically around 0x0600), making it directly accessible to applications in real mode. Early DOS applications and device drivers were developed assuming this layout, with programs loading into the remaining space up to 0xA0000 (640 KB total), as exceeding this would overlap with reserved hardware areas and cause system instability. This expectation became standardized across IBM-compatible PCs, locking conventional memory at 640 KB to maintain backward compatibility.[14] By the late 1980s, the limitation had become notorious as a "640K barrier," often attributed to a quote from Bill Gates claiming "640K ought to be enough for anybody," though Gates has repeatedly denied saying it, and no primary evidence supports the attribution. The barrier highlighted growing software demands outpacing hardware design, prompting workarounds like upper memory utilization, but it underscored the original architecture's constraints on expandability.[15][16]Upper Memory Area Utilization
Structure of Upper Memory Blocks
The Upper Memory Area (UMA), spanning addresses 0xA0000 to 0xFFFFF (640 KB to 1 MB), is fragmented into hardware-reserved regions that create potential gaps for Upper Memory Blocks (UMBs). The video memory region occupies 0xA0000 to 0xBFFFF (128 KB), dedicated to display adapter RAM for modes like those on VGA cards.[12] Immediately following is the adapter space from 0xC0000 to 0xDFFFF (128 KB), which includes video BIOS ROM (typically 0xC0000 to 0xC7FFF, 32 KB) and slots for option ROMs from expansion cards, such as network or SCSI adapters; unused portions here form key gaps if no hardware claims them.[12] The system ROM area covers 0xE0000 to 0xFFFFF (128 KB), with motherboard BIOS in 0xF0000 to 0xFFFFF (64 KB) and extension ROMs in the lower part, further delineating unused regions based on BIOS implementation.[12] These gaps vary significantly with hardware configurations, as installed adapters influence reservation sizes. For instance, EGA or VGA cards may utilize more of the video memory range or extend ROM usage into adapter space, shrinking available free areas compared to simpler CGA setups.[17] In a typical IBM PC-compatible system without extensive peripherals, free UMBs aggregate 128 to 192 KB across multiple non-contiguous blocks, though actual usable space often falls lower due to fragmentation and shadowing.[18] Detection and mapping of UMBs require specialized drivers starting with MS-DOS 5.0. HIMEM.SYS establishes extended memory (XMS) access, allowing EMM386.EXE to probe the UMA for free regions by checking address availability and compatibility, often using enhanced scans like the HIGHSCAN option for precise identification.[19] While EMM386 emulates the Expanded Memory Specification (EMS) interface via INT 67h for related operations, UMB management primarily leverages DOS allocation functions once mapped.[20] UMBs face inherent limitations as non-contiguous allocations, capping usable sizes to individual gaps (e.g., 32-64 KB per block), and remain accessible only in real mode without drivers, invisible to standard DOS programs otherwise.[19] This structure ties directly to the overall DOS memory map's 640 KB conventional limit, where UMB relocation helps mitigate base memory constraints.[12]Accessing and Configuring UMBs
To enable upper memory blocks (UMBs) in MS-DOS, the system first requires access to extended memory, which is managed by loading the HIMEM.SYS device driver in the CONFIG.SYS file; this driver, introduced in MS-DOS 5.0, provides access to memory above 1 MB on systems with an 80286 or higher CPU, including the high memory area (HMA) just above 1 MB.[4][21] For actual UMB creation on 80386 or higher processors, the EMM386.EXE driver (available starting with MS-DOS 5.0) must also be loaded in CONFIG.SYS, as it emulates expanded memory by remapping portions of extended memory into the upper memory area between 640 KB and 1 MB.[4][21] Once UMBs are enabled, configuration involves linking them to the DOS environment and directing device drivers or terminate-and-stay-resident (TSR) programs to load into them. TheDOS=UMB directive in CONFIG.SYS attaches the UMBs to the DOS data segment, allowing core DOS components to utilize upper memory and freeing conventional memory below 640 KB.[4] Similarly, the DEVICEHIGH= command loads specified device drivers into available UMBs rather than conventional memory, provided it follows the EMM386.EXE line in CONFIG.SYS; this must be used judiciously to avoid fragmentation.[4][22]
MS-DOS 6.0 and later include the MEMMAKER utility, which automates UMB configuration by analyzing the system's CONFIG.SYS and AUTOEXEC.BAT files, testing load orders, and relocating drivers and TSRs to upper memory for optimal conventional memory usage.[4] Third-party tools like Quarterdeck's QRAM further optimize UMB allocation on 8086, 80286, and compatible systems by scanning for relocatable components and providing advanced loading options, often achieving higher efficiency than built-in utilities on certain hardware.[23]
UMB access and configuration require at minimum an 80286 CPU for basic extended memory support via HIMEM.SYS, but full UMB functionality with EMM386.EXE demands an 80386 or 80486 processor due to its reliance on protected mode switching.[21] Compatibility issues can arise with certain hardware, such as SCSI host adapters that reserve specific regions in the upper memory area (e.g., for ROM or I/O buffers), rendering those blocks unusable for UMBs and potentially causing allocation failures unless manually excluded via EMM386.EXE parameters.[24]
Software Management Techniques
Role of Device Drivers and TSRs
Device drivers in MS-DOS are loaded during system initialization through directives in the CONFIG.SYS file, where they occupy space in conventional memory as permanent residents to manage hardware interactions.[25] For instance, ANSI.SYS, a common device driver that enables enhanced console functions such as screen control via ANSI escape sequences, typically consumes around 9-10 KB of conventional memory upon loading.[26] Other device drivers, such as those for keyboards or displays, similarly range from 5 to 20 KB each, depending on their functionality and version, contributing to the overall allocation in the first 640 KB of addressable RAM.[27] Terminate-and-stay-resident (TSR) programs, invoked via the AUTOEXEC.BAT file or command line, execute briefly before hooking into system interrupts to remain active in memory for ongoing services like input handling or caching.[18] Examples include MOUSE.COM, a TSR for Microsoft mouse support that uses approximately 9 KB of conventional memory, and SMARTDRV.EXE, a disk caching utility that requires about 2 KB in conventional memory while primarily utilizing extended memory for its buffers.[26][28] KEYB.COM, another TSR for configuring international keyboards, occupies roughly 15 KB.[29] The cumulative effect of multiple device drivers and TSRs in a typical configuration—such as a chain in AUTOEXEC.BAT loading MOUSE.COM, SMARTDRV, and KEYB.COM—can consume 100-200 KB or more, often leaving less than 400 KB of free conventional memory available for applications after boot.[30] This overhead not only reduces usable space within the 640 KB conventional memory limit but also leads to fragmentation, as TSRs allocate blocks that may not be contiguous, complicating subsequent program loading.[18] Loading larger TSRs before smaller ones helps mitigate fragmentation by preserving larger free blocks.[18]Strategies for Loading High
To relocate device drivers and terminate-and-stay-resident (TSR) programs from the first megabyte of RAM into upper memory blocks (UMBs), MS-DOS provides specific commands that attempt to load these components high, provided UMBs are enabled via prior configuration such as HIMEM.SYS and EMM386.EXE with the DOS=HIGH,UMB directive.[31] In the CONFIG.SYS file, the DEVICEHIGH= command loads device drivers into available UMBs; for instance, DEVICEHIGH=C:\DOS\SMARTDRV.SYS places the disk cache driver high instead of in conventional memory below 640 KB. Similarly, in the AUTOEXEC.BAT file, the LH (load high) alias for LOADHIGH attempts to place TSRs such as DOSKEY or mouse drivers into UMBs, as in LH C:\DOS\MOUSE.COM. These commands support a range of standard MS-DOS drivers like ANSI.SYS, RAMDRIVE.SYS, and EGA.SYS, as well as TSRs including NLSFUNC.EXE, GRAPHICS.COM, and SHARE.EXE.[31] The allocation process begins with the DOS linker scanning available UMBs for a suitable contiguous block that fits the program's size; it selects the largest remaining UMB even if a smaller one would suffice, which can lead to fragmentation if not managed carefully. If no adequate UMB space is found, the program falls back to conventional memory, ensuring system stability but forgoing the memory relocation benefit. Program sizes can be assessed using MEM /C while the component is running or by file size for static drivers.[32][31] Best practices emphasize optimizing load order to minimize wasted space in UMBs, as MS-DOS's first-fit-into-largest-block strategy may leave gaps; for example, with UMBs of 4 KB and 3 KB, loading programs of 2 KB, 3 KB, and 2 KB in that sequence (smaller first in this case) fills both blocks fully, whereas starting with the 3 KB program wastes 1 KB in the 4 KB block. Generally, loading larger programs early works well when UMB fragmentation is low, but manual adjustment or tools like MemMaker can automate optimal placement using switches such as /L (specify link strategy) and /S (specify UMB segment) with LOADHIGH.[32] By successfully relocating drivers and TSRs high, these strategies free up substantial conventional memory for applications, often reclaiming dozens of kilobytes per component; for instance, moving SMARTDRV.SYS high preserves its footprint—typically around 20-30 KB—entirely in the upper area, contributing to overall gains of up to several hundred kilobytes depending on the system load. This approach maximizes the 640 KB conventional limit for DOS programs without requiring hardware changes.[31][32]Optimization and Expansion Methods
Driver and TSR Size Reduction
One primary method for reducing the memory footprint of device drivers and terminate-and-stay-resident (TSR) programs in MS-DOS involved editing the CONFIG.SYS file to exclude non-essential drivers, thereby preventing their loading into conventional memory. For instance, users could comment out or remove lines for drivers supporting unused peripherals, such as printer or network interfaces, which often consumed several kilobytes each. This approach, recommended in early optimization guides, allowed for selective loading based on immediate needs, freeing up to 20-50 KB depending on the configuration.[33] To further minimize sizes, developers and users employed built-in or minimal third-party drivers over feature-rich alternatives; for example, MS-DOS's native drivers for basic devices like keyboards were smaller than third-party enhancements, reducing overhead by avoiding extraneous code for advanced features. Conditional compilation during driver development, using directives like#ifdef to exclude unused interrupt handlers or DOS calls, also trimmed resident portions significantly, as detailed in programming references from the era. Additionally, post-loading adjustments, such as redirecting initialization output to NUL (e.g., freeup > nul), eliminated temporary memory allocations during startup.[33]
Compression techniques focused on code efficiency and data packing within TSRs. Inline assembly in compilers like Microsoft C 6.0 or Turbo C produced compact drivers, such as a 600-byte assembly version of LASTDRV compared to a 5,000-byte C equivalent, by replacing high-level calls with direct opcodes. TSRs could swap transient code to disk or high memory after residency, shrinking the conventional allocation; tools like those in 4DOS reduced the shell's footprint to 256 bytes on 286+ systems via environment space release using functions like _dos_setblock(). For shared resources, MS-DOS 6's SHARE.EXE supported options like /L:100 to limit lock records, optimizing its ~4 KB usage without full default settings. Stripping overlays from TSR executables via utilities or manual editing further compacted files before loading.[33]
Analysis began with the MEM command's /C option, which listed loaded programs, their sizes in paragraphs, and allocation details, enabling identification of large residents like a 22 KB mouse driver at segment OBEAh. Users could then replace such drivers—for example, swapping a full-featured mouse handler (e.g., 27 KB) with a lightweight alternative under 10 KB—to reclaim space. Historical utilities from the 1980s and 1990s, such as INTRSPY for interrupt and memory chain auditing or DEBUG for inspecting memory control blocks (MCBs), facilitated deeper trimming by revealing redundant code or unused heaps. Memory Commander, a commercial tool, provided graphical auditing to detect and relocate oversized TSRs, often recovering 10-30 KB through automated suggestions. These methods complemented relocation strategies like loading high but prioritized inherent size reduction for sustained gains.[33][34]