以前、8086や80186 CPUが栄えていた頃は、メモリのアクセス上限は1MBでした。これは16進数に直すと0xFFFFFであり、20本のアドレスバス(A00-A19)で表す事ができます。
やがて80286が開発され、メモリのアクセス上限は16MB(0xFFFFFF)となり、アドレスバスも24本(A00-A23)に拡張されました。しかし、メモリアクセスの時8086と80286では互換性がなくなり、8086上で動作していたプログラムが80286上で動かない事が発生します。
例えば、次のようなコードは8086と80286では、結果が異なってしまいます。
1: movw $0xffff,%ds /* データセグメントに0xFFFFを代入 */ 2: movw $0x000f,%bx /* bx registerに0x000fを代入 */ 3: move $0x1111,(%bx) /* [0xFFFF]:[0x000F] = 0x1111 */ 4: incw $bx /* bxをインクリメント bx = 0x0010 */ 5: move $0x2222,(%bx) /* [0xFFFF]:[0x0010] = 0x2222 */ /* 80286の場合は 0x100000 = 0x2222 */ /* 8086の場合は 0x00000 = 0x2222 */ 6: movw $0x0000,%ds /* データセグメントに0x0000を代入 */ 7: movw $0x0000,%bx /* bx registerに0x0000を代入 */ 8: move (%bx),$ax /* ax = [0x0000]:[0x0000] */
上記ソースの3行目では、メモリーの0xFFFFF番地に0x1111を書込んでいます。これは8086/80286 CPU共に同じ動作になります。
しかし、の5行目では8086と80286では、結果が異なってきます。[0xFFFF]:[0x0010]のリニアアドレスは0x100000となりますが、8086 CPUはアドレスバスが20本しか無い為、0x100000はオーバーフローしてしまい0x00000となり、メモリの0番地目に0x2222が書込まれます。
一方、80286 CPUはアドレスバスを24本持っていますので、オーバーフローせずメモリの0x100000番地に0x2222が書込まれます。

この為に、8行目の結果は、「8086 CPUの場合ax=0x2222」「80286 CPUの場合ax=不定」となり、8086 CPUで動いていたプログラムが80286 CPUでは動かない事が起こり、互換性の点で問題が出てきてしまいます。
上記の互換性を保つため、80286以降のマザーボードにはA20マスク回路を追加しました。この回路が有効になっているとA20の信号を常に0に書き換える働きをします。つまり0x100000-0x1FFFFFまでの範囲は、0x00000-0xFFFFFに変換される事になります。