PC Memory - A tutorial on PC memory and hex arithmetic

Funny Little Numbers

The craft of programming is replete (filled to excess) with funny little numbers.

In this article I shall refer to numbers in two ways.

One way is to specify the number in decimal, just by stating it. Eg: 1024.

The other way is to specify the number in hexadecimal. I shall use the convention of preceding every hex number with 0x. Eg: 0xF = 15.

Other writers use the convention of appending an 'h' or an 'H' to hex numbers. Thus FH = Fh = 15.


    1 Kb = 1 Kilobyte = 1024 bytes.
    1 Mb = 1 Megabyte = 1024 * 1 Kb = 1,048,576 bytes.
    1 Gb = 1 Gigabyte = 1024 * 1 Mb = heaps.

A Detour

The preceding would suggest 360 Kb floppies hold 360 * 1024 = 368,640 bytes of data. They don't.

Floppy disk sizes (that is, available space):

     360 Kb = 362,496 bytes.
     720 Kb = 730,112 bytes.
     1.2 Mb = 1,213,592 bytes.
    1.44 Mb = 1,457,664 bytes.

Memory Addresses

Just to make things difficult, memory addresses are normally written not as one but as two hex numbers. Eg: 0x9FFF:000F. On the left of the colon is the Segment part, and on the right is the Offset part.

What does this number really mean? Well, the Segment and Offset parts are added by shifting the Segment left one (hex) digit and then adding the Offset, thus:

    +   0x 000F
    =   0x9FFFF
    =   655,359

Now, 0 to 655,359 is the same as 1 to 655,360. That is, 1 to 640 Kb. Lo and behold! The infamous 640 Kb DOS memory limit consists of memory addresses from 0 to 655,359, that is, 0 to 0x9FFF:000F.

Another example: 1 Mb of memory occupies addresses from 0 to 0xFFFF:000F. That is, since 1 Mb = 1,048,576, 0 to

    +   0x 000F
    =   0xFFFFF
    = 1,048,575

Note also that a memory address can be written in many equivalent ways. 0x000F:0045 = 0x0010:0035 = 0x0011:0025 = 0x0013:0005.

Let's see what these mean:

    +   0x 0005
    =   0x00135
    =       309

    +   0x 0045
    =   0x00135
    =       309

That is, all represent physical address 309. By convention, when the Offset part is from 0 to 0xF the address is said to be Normalized. Thus 0x0013:0005 is Normalized, whereas the other forms aren't.

Common Values

    0xFFFF = 65535
    0xFF   =   255

Since 0xFF = 255, then 0 to 0xFF = 0 to 255. Now, in 0 to 255 there are 256 different values, which is precisely how many different values can be represented in 8 bits. And 8 bits is a byte!

So all values from 0 to 0xFF can be stored in 1 byte, and all values from 0 to 0xFFFF can be stored in 2 bytes (1 word on some machines. Some machines use 4 bytes per word).

Consequently, it takes 2 bytes to hold a Segment part and 2 bytes to hold an Offset part.

Finally then, it takes 4 bytes to hold a complete memory address of the form Segment:Offset.

A Memory Map

      1 Mb   = 0x10000:0000

    1 Mb-1   = 0xFFFF:000F  End System BIOS area
    960 Kb     0xF000:0000  | = 128 Kb
    896 Kb     0xE000:0000  Start System BIOS area

    896 Kb-1 = 0xDFFF:000F  End Expansion card BIOS area
    832 Kb     0xD000:0000  | = 128 Kb
    768 Kb     0xC000:0000  Start Expansion card BIOS area

    768 Kb-1 = 0xBFFF:000F  End Video RAM
    704 Kb     0xB000:0000  | = 128 Kb
    640 Kb     0xA000:0000  Start Video RAM

    640 Kb-1 = 0x9FFF:000F  End DOS RAM
    576 Kb     0x9000:0000  |
    512 Kb     0x8000:0000  |
    448 Kb     0x7000:0000  |
    384 Kb     0x6000:0000  |
    320 Kb     0x5000:0000  | = 640 Kb
    256 Kb     0x4000:0000  |
    192 Kb     0x3000:0000  |
    128 Kb     0x2000:0000  |
     64 Kb     0x1000:0000  |
      0 Kb     0x0000:0000  Start DOS RAM


Random Access (read/write) Memory. This is a generic term which applies equally to Conventional Memory, Expansion Memory, Extended Memory, Expanded Memory and (perhaps) CMOS Memory.


Read-Only Memory. A chip with an unchangeable bit pattern burned into it. The bit pattern may in fact be data or a program.

PROM = Programmable Read-Only Memory

Writing into a read-only chip sounds like a contradiction in terms. What it means is that by putting the chip in some piece of special equipment (a PROM burner) the input current can be made so high that a bit pattern is forced into the chip despite its 'read-only' design.

When such a chip is put in a PC it is read-only because the design of the PC ensures such high currents do not appear on the chip's input lines, except during a catastrophe!

EPROM = Erasable Programmable Read-Only Memory

In other words, you can obliterate the existing bit pattern and re-program the chip, perhaps repeatedly, as you debug the program.

In contradistinction to the English saying 'crash-and-burn', this programming technique is called 'burn-and-crash'. First you burn the program into the chip. Then you run the program and it crashes...

POST = Power On Self Test.

That is, when the power is switched on, the machine runs a self-test program. Guess where the POST program is stored. Right! In ROM. Part of this self-test is the determination of the amount of physical memory in the machine. The result is stored in CMOS.

BIOS = Basic Input-Output System

This is actually the name of a program which has been burned into a chip. The chip is a ROM chip.

This BIOS is a feature of Intel microprocessors, rather than of DOS. See p 68 of The MS-DOS Encyclopedia.

When the computer starts running the microprocessor automatically begins executing code at 0xFFFF:0000. It does this by setting the Code Segment (CS) register to segment 0xFFFF, and the Instruction Pointer (IP) register to 0x0000.

Thus CS:IP points to (contains) 0xFFFF:0000, and it is from this address that the CPU takes the next instruction to be executed.

This instruction is usually a jump to the BIOS's initialization code, after which the code scans bootable drives looking for a copy of DOS (or some other operating system) to load and run.


Same as BIOS.

ROM BIOS Extensions

More programs in ROM chips. Usually, each expansion card in your machine will have on it a ROM chip containing a program - a ROM BIOS Extension. The program is dedicated to control of that expansion card.

ROM BIOS Extensions are sometimes called Supplementary ROM support.

These ROM BIOS Extensions are executed at boot time because the one true ROM BIOS scans memory addresses from 0xC000:0000 to 0xE800:0000 (or, says the MS-DOS Encyclopedia, from 0xA000:0000 to 0xF000:0000) in 2 Kb jumps, looking for signature bytes. These bytes, 0x55 0xAA I believe, indicate code is lurking at that address, waiting to be executed.

When the BIOS code sees the signature it jumps to that address (or maybe just beyond it), and the code is executed. This gives the ROM BIOS Extension the chance the strut its stuff. Most likely it will do two things: (1) Execute initialization code, and (2) store into DOS's Interrupt Table the address of its Strategy Routine - that is the code to which DOS is to jump when an interrupt of the appropriate type occurs.

You can look for this signature using Debug as follows. The '-' below is Debug's prompt. The 'd' means dump (i.e. display) memory starting from the given address. The 'q' means quit. Each line is terminated with an <Enter>. This process is quite safe.

Warning. Hex numbers in Debug do not have 0x signs.

        -d C000:0
        -d C800:0

The output looks like:

        C000:0000 55 AA ...
        C000:0010 AB CD ...

This means Segment 0xC000 is being dumped. The first line consists of bytes whose Offsets are 0x0000 to 0x000F (0 to 15). The second consists of bytes 0x0010 to 0x001F (16 to 31).

Debug always puts a '-' in the middle of the line.

Alternately, run the Norton utility SI - System Information.

Another example: At 0xFFFF:000E is the machine ID byte. If you examine this byte you might find one of these values:

        Value     Machine
        0xFF      PC
        0xFE      XT
        0xFD      PC jr
        0xFC      AT
        0xFB      XT/2
        0xFA      PS/2 model 30
        0xF9      Convertible
        0xF8      PS/2 model 80


        -d FFFF:0

The output looks like:

    FFFF:0000 EA 5B E0 00 F0 30 31 2F-31 35 2F 38 38 FF FC 00

30 31 2F 31 35 2F 38 38 is just 01/15/88, i.e. a date in Month/Day/Year format.

Further, since this line is bytes 0x0000 to 0x000F, the second last is byte 0x000E, i.e. 0xFFFF:000E. You can see its value is 0xFC. Thus the machine is an AT.

Given a lot of other information which I'll skip, it is possible to determine the machine sub-model. Eg: there are three (3) types of XTs, not counting the PS/2 pseudo-XTs.

CMOS Memory = Complementary Metal-Oxide Semiconductor (read/write) Memory

In other words, RAM.

CMOS is only present in AT class machines. Earlier machines, PCs and XTs, don't have it.

This type of RAM consumes an extremely small amount of power. The data in it is preserved, when the machine's power is off, by torch-style batteries.

CMOS holds certain configuration data describing the machine's hardware, as well as the date and time.

CMOS normally consists of just 64 bytes.

Many AT class machines come with a program called SETUP which allows you to read and write the values in CMOS. In some machines this program is not on disk, but in ROM. During the POST the checksum of the CMOS is calculated, and if the calculated value does not match the value stored in CMOS the SETUP program is run, or at least a message appears giving you a choice of running it or ignoring the error.

Of course, given the format of the CMOS memory and the format of the read and write commands required, you can access this memory with your own program.

Conventional Memory

This is the term for memory up to 1 Mb.

This Conventional Memory is directly addressable by an Intel microprocessor (running DOS, say, in Real Mode).

In fact, machines which are alleged to come with only 640 Kb of RAM will always comes with at least some memory in the range 640 Kb to 1 Mb. After all, they need Video RAM (at 0xA000:0000) to use a screen, and all 8086/8088-compatible microprocessors will have a BIOS (at 0xF000:0000).

DOS and other programs occupy the region 0 to 640 Kb.

If the machine has only 512 Kb, a gap exists from 512 Kb to 640 Kb. However, there will still be some memory above 640 Kb, as stated above.

In other words, memory need not be contiguous. There can be gaps in it, meaning there literally is no memory at certain addresses (address ranges).

In fact, IBM generously delivered my AT with a whopping 128 Kb of Conventional Memory! That's why I bought an Extended Memory card... The latter has 2 Mb on it, 512 Kb of which is used to 'backfill' Conventional Memory up to 640 Kb (128 + 512), while the other 1536 Kb (2048 - 512) is used for a RAM disk.

Interrupt Vector Table

The first 1 Kb of Conventional Memory holds the Interrupt Vector Table, which consists of 256 addresses, each of 4 bytes.

Remember, it takes 4 bytes to hold a memory address of the form Segment:Offset.

Each 4-byte address is called an interrupt vector, and is allocated to an interrupt of a specific type.

When an interrupt occurs, the CPU saves the state of the machine and jumps to the corresponding interrupt address. The code pointed to is a Strategy Routine which handles its own interrupt and returns. The CPU restores the state of the machine and continues executing the interrupted program.

Eg: every time a key is pressed or released, interrupt 0x09 is triggered. That is, the CPU jumps to the address stored in bytes 0x24 to 0x27.

Various programs (the BIOS, ROM BIOS Extensions and user programs) store addresses into this first 1 Kb. By doing so they announce they will handle interrupts of the type whose address they have changed to point to themselves. This process is called 'hooking an interrupt'.

Let's take the case of a non-BIOS program. Eg: we might write a program such that when a particular key is hit, the program 'pops-up'.

From the program's point of view, here's what happens:

        1. The program is written in such a way that part of it is a Strategy Routine
                for a given interrupt.
        2. The program is run by the user.
        3. While running, the program determines the address in memory of its Strategy
        4. The program stores this address in the interrupt vector table, at the address
                corresponding to key-stroke interrupts.
        5. The program jumps into DOS via interrupt 0x21, and requests DOS that it, the
                program, Terminate-and-Stay-Resident (TSR).
        6. Thereafter, whenever the user hits a key, the key-stroke interrupt is executed.
                The Strategy Routine examines the key-stroke and decides whether or not to

In reality, we wouldn't hook interrupt 0x09, which is executed twice per key-stroke (press, release). We'd hook interrupt 0x16, which is executed every time a complete key-stroke is available in the BIOS's key-board buffer.

Since DOS was not designed to cleanly support such manoeuvres, such programming is fraught with difficulties...

Extended Memory

PCs and XTs can't have Extended Memory.

It is memory beyond the 1 Mb boundary. That is, its physical address starts at 1 Mb. There can be up to 15 Mb of Extended Memory.

It is only addressed by a 286/386 processor running in Protected Mode. Since DOS runs in Real Mode, it (DOS) cannot directly address Extended Memory, let alone execute code residing in the latter. However, some software can access this memory.

In fact, there are several ways to access it.

        1. Use a DOS program like VDISK or RAMDRIVE to treat the memory as a RAM disk.
        2. Use certain DOS functions to transfer blocks of data between Conventional
                Memory and Extended Memory.
        3. Use an Extended Memory Manager written to the Extended Memory Specification.
                These have names like HIMEM.SYS, 386^MAX, QEMM...

Expansion Memory

This is IBM's phrase for Extended Memory. I kid you not.

IBM ATs come with a diagnostic floppy. Booting from this enables you to store and change values in CMOS.

When specifying the amount of Extended Memory in your machine, you do it when the SETUP program asks for Expansion Memory.

Clear? I'm so glad.

By the way, this SETUP program has a menu choice for copying floppies. You must use it to copy the diagnostics floppy itself. If you use DISKCOPY to copy the diagnostics floppy, there are no error messages, but the resultant copy will not boot.


The Extended Memory Specification. It is a systematic method for reading and writing Extended Memory. This spec is much more recent than the Expanded Memory Specification (EMS).

Expanded Memory

PCs, XTs and ATs can all have Expanded Memory.

Access to it is via the EMS, a hardware and software combination to circumvent the 1 Mb addressing limit of the Intel processors operating in Real Mode. I'll refer to it as EMS Memory. The software is called an Expanded Memory Manager (EMM).

There can be up to 8 Mb of EMS Memory.

It's physical address doesn't sit beyond the 1 Mb boundary. In fact, it doesn't sit anywhere. This is explained in LIM 3.2 below.


The Expanded Memory Specification. It is a systematic method for reading and writing Expanded Memory. This spec has gone through several versions.

EMS is now taken to mean EMS 4.0.

LIM 3.2

Lotus/Intel/Microsoft: These companies produced the first EMS, version 3.2, which is thus known as LIM 3.2.

It allows programs to map (utilize) pages of Expanded Memory, each of 16 Kb. At most, 4 such pages can be mapped at once.

Mapping means the pages have their addresses fiddled so that they look like they reside in the address range 640 Kb to 1 Mb. This in turn means they are accessible by DOS, but cannot reside in the lower 640 Kb address range.


The Enhanced Expanded Memory Specification. This followed LIM 3.2. It was designed by AST Research, Quadram and Ashton-Tate.

It allows programs to map up to 64 pages at a time. Pages can be mapped into the address range 0 Kb to 1 Mb.

EMS 4.0

The LIM companies upgraded EMS to be a super-set of EEMS, producing EMS version 4.0 in the process. AST Research, Quadram and Ashton-Tate then came to the party.

Expanded-Enhanced Confusion

As if all that madness wasn't enough, there is Expanded Memory and Expanded Memory.

Some PC memory expansion cards contain hardware support for EMS 4.0, as well as the memory chips themselves, and thus this memory is absolutely Expanded Memory. However, an EMS Manager can make some or all of it look like Extended Memory.

Some expansion cards don't have this hardware support, and thus the memory is absolutely Extended Memory. However, an EMS Manager can make some or all of it look like Expanded Memory.

Lastly, a few early expansion cards had hardware support for only 4 pages of Expanded Memory, not 64 pages, and thus don't fit the definition of EMS 4.0. At the worst they are misrepresented as being EMS 4.0 compatible. They aren't.

Now, does it matter? Yes, but first another detour.

Physical Memory

This is the amount of memory held in two (2) places in CMOS. It is Extended Memory. One value is the amount specified by the user of the SETUP program. The other value is the amount detected during the POST.

These values do not include Expanded Memory with hardware support.

These values do include Extended Memory made to look like Expanded Memory by an EMS Manager.

Don't forget, at the time of the POST the EMS Manager has not yet started running. After the POST, DOS will be loaded and CONFIG.SYS will be processed. A command in CONFIG.SYS will load the EMS Manager.

Going back to the POST, memory will be of three types:

        - Conventional Memory.
        - Expanded Memory forced to look like Expanded Memory by the presence of
                hardware support.
        - Extended Memory, i.e. everything else.

It matters, sometimes

I have just written a program which displays the amount of memory in a machine. Simple, you'd think. It wasn't.

Eg: DOS might tell you Total Extended Memory is 0, because an XMS Manager is installed.

On the other hand, getting Physical Extended Memory from CMOS is not definitive, because an EMS Manager might be supplying extra Extended Memory out of Expanded Memory.


8086/8088-compatible microprocessors run in Real Mode.

The 286/386/486 series can run in Real or Protected Mode.

Now, what do these Modes mean?

In short, very short, I'll just say: Be aware that in Protected Mode the microprocessor can execute certain privileged instructions not available in Real Mode. In other words the chip is more powerful in Protected Mode than in Real Mode.

This begs the question: Why manufacture a chip like this?

The simple answer is that many years ago when the 8086/8088s were being designed, chip fabrication technology was only good enough to allow Real Mode chips to be manufactured. Don't forget the design constraints of simplicity and an incredibly cheap retail price.

The real answer is that at first technology restricted the sophistication of the chip, for sure, but later new technology enabled a chip to be manufactured whose design (Real/Protected Mode) modelled the human brain (Conscious/Unconscious Mode).

Similarly, humans create institutions which also model the brain. Take democracy for example.

It is implemented with two Houses of Parliament:

    State       Real                 Protected
    Victoria    Legislative Council  Legislative Assembly
    Australia   Senate               House of Representatives
    England     House of Lords       House of Commons
    America     Congress             House of Representatives
    Brain       Conscious            Unconscious
    Literature  Dr. Jekyll           Mr. Hyde (hide, get it?)

This arrangement contrasts nicely with that pertaining in a dictatorship...


        0x0000:0000 to 0x9FFF:000F = 640 Kb of DOS RAM.
        0xB800:0000 to 0xBFFF:000F = 32 Kb of Video RAM.
        0xC000:0000 to 0xC9FF:000F = 32 Kb of Video (EGA/VGA) BIOS, that is, a ROM
                BIOS Extension.
        0xCA00:0000 to 0xCFFF:000F = 32 Kb of Floppy controller card BIOS, that is,
                a ROM BIOS Extension.

Note 1: The Video BIOS and Floppy controller card BIOS are not really exactly 32 Kb long.

Note 2: Using Debug to dump memory, I see that printable text (displayed during booting) in the Floppy controller card BIOS actually starts at 0xC9EF:0378.

An Unreal Memorex Telex AT

        0x0000:0000 to 0x9FFF:000F = 640 Kb of DOS RAM.
        0xB800:0000 to 0xBFFF:000F = 32 Kb of Video RAM.
        0xC000:0000 to 0xC9FF:000F = 32 Kb of Video (VGA) BIOS.


Ron Savage.

Home page:


Australian Copyright © 2002 Ron Savage. All rights reserved.

	All Programs of mine are 'OSI Certified Open Source Software';
	you can redistribute them and/or modify them under the terms of
	The Artistic License, a copy of which is available at: