*** Welcome to piglix ***

A20 line


The A20, or addressing line 20, is one of the electrical lines that make up the system bus of an x86-based computer system. The A20 line in particular is used to transmit the 21st bit on the address bus.

A microprocessor typically has a number of addressing lines equal to the base-two logarithm of its physical addressing space. For example, a processor with 4 GB of physical addressing space requires 32 lines, which are named A0 through A31. The lines are named after the zero-based number of the bit in the address that they are transmitting. The least significant bit is first and is therefore numbered bit 0 and signaled on line A0. A20 transmits bit 20 (the 21st bit) and becomes active once addresses reach 1 MB, or 220.

The early Intel 8086, Intel 8088, and Intel 80186 processors had 20 address lines, numbered A0 to A19; with these, the processor can access 220 bytes, or 1 MB. Internal address registers of such processors only had 16 bits. To access a 20-bit address space, an external memory reference was made up of a 16-bit Offset address added to a 16-bit Segment number, shifted 4 bits so as to produce a 20-bit physical address. The resulting address is equal to Segment * 16 + Offset. There are many combinations of segment and offset that produce the same 20-bit physical address. Therefore, there were various ways to address the same byte in memory. For example, here are four of the 4096 different segment:offset combinations, all referencing the byte whose physical address is 0x000FFFFF (the last byte in 1 MB-memory space):

Referenced the last way, an increase of one in the offset yields F800:8000, which is a proper address for the processor, but since it translates to the physical address 0x00100000 (the first byte over 1 MB), the processor would need another address-line for actual access to that byte. Since there is no such line on the 8086 line of processors, the 21st bit above, while set, gets dropped, causing the address F800:8000 to "wrap around" and to actually point to the physical address 0x00000000.

To improve performance, a trick was used by some DOS programmers, for example, to have one segment that has access to program data (such as from F800:0000 to F800:7FFF, pointing to the physical addresses 0x000F8000 - 0x000FFFFF) as well as the I/O data (such as the keyboard buffer) that was located in the first memory segment (with addresses F800:8000 to F800:FFFF pointing to the physical addresses 0x00000000 to 0x00007FFF).. The address wrap was also used by MS-DOS itself, to implement the CALL 5 entry point in the Program Segment Prefix; the CALL 5 handler was at physical address 0x000000C0 but for CP/M compatibility, its offset had to match the segment size (usually 0xFEF0). The only way to reconcile them was to choose a segment value that when added to 0xFEF0, resulted in a physical address of 0x001000C0, which would wrap around to 0x000000C0.


...
Wikipedia

...