<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh-Hans-CN">
	<id>http://wiki.foofun.cn//index.php?action=history&amp;feed=atom&amp;title=A20_Line</id>
	<title>A20 Line - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.foofun.cn//index.php?action=history&amp;feed=atom&amp;title=A20_Line"/>
	<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=A20_Line&amp;action=history"/>
	<updated>2026-04-07T11:37:56Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>http://wiki.foofun.cn//index.php?title=A20_Line&amp;diff=1130&amp;oldid=prev</id>
		<title>2022年4月2日 (六) 07:25 Zhang3</title>
		<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=A20_Line&amp;diff=1130&amp;oldid=prev"/>
		<updated>2022-04-02T07:25:51Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;zh-Hans-CN&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;←上一版本&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;2022年4月2日 (六) 07:25的版本&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l107&quot;&gt;第107行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第107行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==启用==&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;==启用==&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;有几个使能A20的信号源，通常每一个输入被或运算在一起以形成A20使能信号。 这意味着使用一种方法 &lt;/del&gt;(如果芯片组支持) &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;就足以启用A20。 如果要禁用A20，可能必须禁用所有现有源。 &lt;/del&gt;始终通过如上所述测试线路来确保A20具有请求的状态。&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;有几个使能A20的方法来源，通常每一个输入或合在一起以形成A20使能信号。 但这也意味着使用一种方法 &lt;/ins&gt;(如果芯片组支持) &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;也许就足以启用A20。 而如果要禁用A20，可能必须禁用所有现有源。 &lt;/ins&gt;始终通过如上所述测试线路来确保A20具有请求的状态。&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== 键盘控制器 ===&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;=== 键盘控制器 ===&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l137&quot;&gt;第137行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第137行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/source&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/source&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;or in &lt;/del&gt;[[assembly]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;或在&lt;/ins&gt;[[assembly&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|汇编&lt;/ins&gt;]]&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;中&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l202&quot;&gt;第202行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第202行：&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/source&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;/source&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;正如在 [http://www.win.tue.nl/~ aeb/linux/kbd/A20.html 参见站点]中提到的，最好仅在必要时进行写入，并确保位0为0，因为它用于快速重置。 下面是一个例子：&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;正如在 [http://www.win.tue.nl/~aeb/linux/kbd/A20.html 参见站点]中提到的，最好仅在必要时进行写入，并确保位0为0，因为它用于快速重置。 下面是一个例子：&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;source lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Zhang3</name></author>
	</entry>
	<entry>
		<id>http://wiki.foofun.cn//index.php?title=A20_Line&amp;diff=1129&amp;oldid=prev</id>
		<title>Zhang3：创建页面，内容为“A20地址线是任何内存访问的第21位 (从0开始计数到数字20) 物理表示。（译者注：A20 Address Line启用设置是一种为了兼容而保留的技术，一般使用需要设置1启用） 当IBM-AT（Intel 286）推出时，它能够访问多达16兆字节的内存（而不是8086的1兆字节）。 但为了保持与8086的兼容性，必须在AT中复制8086体系结构中的一个怪癖(内存地址折回-memory wraparound)。 为此，…”</title>
		<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=A20_Line&amp;diff=1129&amp;oldid=prev"/>
		<updated>2022-04-02T07:19:01Z</updated>

		<summary type="html">&lt;p&gt;创建页面，内容为“A20地址线是任何内存访问的第21位 (从0开始计数到数字20) 物理表示。（译者注：A20 Address Line启用设置是一种为了兼容而保留的技术，一般使用需要设置1启用） 当IBM-AT（Intel 286）推出时，它能够访问多达16兆字节的内存（而不是8086的1兆字节）。 但为了保持与8086的兼容性，必须在AT中复制8086体系结构中的一个怪癖(内存地址折回-memory wraparound)。 为此，…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;A20地址线是任何内存访问的第21位 (从0开始计数到数字20) 物理表示。（译者注：A20 Address Line启用设置是一种为了兼容而保留的技术，一般使用需要设置1启用） 当IBM-AT（Intel 286）推出时，它能够访问多达16兆字节的内存（而不是8086的1兆字节）。 但为了保持与8086的兼容性，必须在AT中复制8086体系结构中的一个怪癖(内存地址折回-memory wraparound)。 为此，默认情况下，地址总线上的A20线被禁用。&lt;br /&gt;
&lt;br /&gt;
这是因为8086只能访问1兆字节的内存， 但由于分段内存模型，它可以有效地寻址高达1M字节和64K字节(减去16字节)。  因为8086上有20个地址线 (A0到A19)，所以1兆字节标记以上的任何地址都折回为零。 出于某种原因，一些目光短浅的程序员会编写实际使用这种折回行为的程序 (而不是在内存底部的正常位置直接寻址内存)。  因此，为了在新处理器上支持这些8086时代的程序，必须在IBM AT及其兼容性上模拟这种折回； 这最初是通过锁存器（latch）实现的，默认情况下，锁存器将A20线设置为零。（译者注：也就是保持和原来旧CPU的内存地址溢出后的归零折回一样的特性） 后来，486将逻辑添加到处理器中，并引入了A20M引脚来控制它。&lt;br /&gt;
&lt;br /&gt;
对于操作系统开发人员 (或 [[Bootloader]] 开发人员)，这意味着必须启用A20线路，以便可以访问所有内存。 这一开始只是一个简单的黑客技巧，但最后又加入更简单的方法来应对它， 导致编写肯定会启用它的代码变得更加困难，而编写肯定会禁用它的代码也变得更加困难。&lt;br /&gt;
&lt;br /&gt;
== 键盘控制器 ==&lt;br /&gt;
A20线使能的传统方法是直接探测键盘控制器。 原因是英特尔的[[&amp;quot;8042&amp;quot; PS/2 Controller|8042键盘控制器]]有一个备用引脚，他们决定通过该引脚控制A20线路。 考虑到它们（内存和键盘）的设计目的毫无关系，这在现在看来似乎是愚蠢的，但是当时计算机还没有那么标准化。 键盘控制器通常是[http://www.diakom.ru/el/elfirms/datashts/Smsc/42w11.pdf 8042]芯片。 通过对该芯片进行精确编程，你可以启用或禁用地址总线上的位#20。&lt;br /&gt;
&lt;br /&gt;
当你的PC启动时，A20 gate通常被禁用，但是一些BIOS (和仿真器，如QEMU) 确实为你启用了它，一些高内存管理器 (HIMEM.SYS) 或引导加载器 ([[GRUB]]) 也会这么做。&lt;br /&gt;
&lt;br /&gt;
==测试A20线==&lt;br /&gt;
在使用下面介绍的任何方法启用A20之前，最好测试A20地址线是否已由[[BIOS]]启用。 这可以通过将位于地址0000:7DFE处的引导扇区标识符 (0xAA55) 与位于地址FFFF:7E0E处的值更高的1MIB进行比较来实现。 当两个值不同时，这意味着A20已启用，否则如果值相同，则必须排除看看这是不是偶然。 因此，需要更改引导扇区标识符，例如通过将其向左旋转8位，并再次与FFFF:7E0E处的16位字进行比较。 当它们仍然相同时，A20地址线是被禁用的，否则是被启用的。&lt;br /&gt;
&lt;br /&gt;
下面的代码执行检查（不像上面描述的那样——更直接）。&lt;br /&gt;
&amp;lt;SOURCE lang=“ASM”&amp;gt;&lt;br /&gt;
; 以下代码是公共领域许可的&lt;br /&gt;
&lt;br /&gt;
[bits 16]&lt;br /&gt;
&lt;br /&gt;
; Function: check_a20&lt;br /&gt;
;&lt;br /&gt;
; 目的：以完全独立的状态保存方式检查a20线路的状态。&lt;br /&gt;
;          如果不需要完全的自包含(self-containment)，可以根据需要对该函数进行修改&lt;br /&gt;
;          删除开头的push和结尾的pop。&lt;br /&gt;
;&lt;br /&gt;
; 如果a20线被禁用（内存出现折回），则返回: ax中的0&lt;br /&gt;
; 如果启用了A20线路，则为AX中的1(内存不折回)&lt;br /&gt;
&lt;br /&gt;
check_a20:&lt;br /&gt;
    pushf&lt;br /&gt;
    push ds&lt;br /&gt;
    push es&lt;br /&gt;
    push di&lt;br /&gt;
    push si&lt;br /&gt;
&lt;br /&gt;
    cli&lt;br /&gt;
&lt;br /&gt;
    xor ax, ax ; ax = 0&lt;br /&gt;
    mov es, ax&lt;br /&gt;
&lt;br /&gt;
    not ax ; ax = 0xFFFF&lt;br /&gt;
    mov ds, ax&lt;br /&gt;
&lt;br /&gt;
    mov di, 0x0500&lt;br /&gt;
    mov si, 0x0510&lt;br /&gt;
&lt;br /&gt;
    mov al, byte [es:di]&lt;br /&gt;
    push ax&lt;br /&gt;
&lt;br /&gt;
    mov al, byte [ds:si]&lt;br /&gt;
    push ax&lt;br /&gt;
&lt;br /&gt;
    mov byte [es:di], 0x00&lt;br /&gt;
    mov byte [ds:si], 0xFF&lt;br /&gt;
&lt;br /&gt;
    cmp byte [es:di], 0xFF&lt;br /&gt;
&lt;br /&gt;
    pop ax&lt;br /&gt;
    mov byte [ds:si], al&lt;br /&gt;
&lt;br /&gt;
    pop ax&lt;br /&gt;
    mov byte [es:di], al&lt;br /&gt;
&lt;br /&gt;
    mov ax, 0&lt;br /&gt;
    je check_a20__exit&lt;br /&gt;
&lt;br /&gt;
    mov ax, 1&lt;br /&gt;
&lt;br /&gt;
check_a20__exit:&lt;br /&gt;
    pop si&lt;br /&gt;
    pop di&lt;br /&gt;
    pop es&lt;br /&gt;
    pop ds&lt;br /&gt;
    popf&lt;br /&gt;
&lt;br /&gt;
    ret&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 从保护模式测试A20线路 ===&lt;br /&gt;
&lt;br /&gt;
在受保护模式下，测试A20更容易，因为你可以使用任何奇数兆字节地址访问A20的设置内存地址，并将其与偶数兆字节的邻居进行比较。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;br /&gt;
[bits 32]&lt;br /&gt;
&lt;br /&gt;
; 检查A20线路设置&lt;br /&gt;
; 如果A20 gate被清除0，则返回给调用者。&lt;br /&gt;
; 如果设置了A20行，则继续到A20_on运行。&lt;br /&gt;
; 作者Elad Ashkcenazi &lt;br /&gt;
&lt;br /&gt;
is_A20_on?:   &lt;br /&gt;
&lt;br /&gt;
pushad&lt;br /&gt;
mov edi,0x112345  ;odd megabyte address.&lt;br /&gt;
mov esi,0x012345  ;even megabyte address.&lt;br /&gt;
mov [esi],esi     ;确保两个地址都包含不同的值。&lt;br /&gt;
mov [edi],edi     ;( 如果清除了A20线路设置为0，则两个指针将指向包含0x112345 (edi) 的地址0x012345) &lt;br /&gt;
cmpsd             ;比较地址以查看它们是否相同。&lt;br /&gt;
popad&lt;br /&gt;
jne A20_on        ;如果不等效，则设置A20行。&lt;br /&gt;
ret               ;如果等效，A20线路已被清除为0。&lt;br /&gt;
&lt;br /&gt;
A20_on:&lt;br /&gt;
;*此处是你的代码*&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==启用==&lt;br /&gt;
有几个使能A20的信号源，通常每一个输入被或运算在一起以形成A20使能信号。 这意味着使用一种方法 (如果芯片组支持) 就足以启用A20。 如果要禁用A20，可能必须禁用所有现有源。 始终通过如上所述测试线路来确保A20具有请求的状态。&lt;br /&gt;
&lt;br /&gt;
=== 键盘控制器 ===&lt;br /&gt;
对于最初启用A20线路的方法，需要一些使用键盘控制器芯片（8042芯片）的硬件IO。&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
void init_A20(void)&lt;br /&gt;
{&lt;br /&gt;
   uint8_t   a;&lt;br /&gt;
&lt;br /&gt;
   disable_ints();&lt;br /&gt;
&lt;br /&gt;
   kyb_wait_until_done();&lt;br /&gt;
   kyb_send_command(0xAD);         // disable keyboard&lt;br /&gt;
&lt;br /&gt;
   kyb_wait_until_done();&lt;br /&gt;
   a=kyb_get_data();&lt;br /&gt;
&lt;br /&gt;
   kyb_wait_until_done();&lt;br /&gt;
   kyb_send_command(0xD1);         // Write to output&lt;br /&gt;
&lt;br /&gt;
   kyb_wait_until_done();&lt;br /&gt;
   kyb_send_data(a|2);&lt;br /&gt;
&lt;br /&gt;
   kyb_wait_until_done();&lt;br /&gt;
   kyb_send_command(0xAE);         // enable keyboard&lt;br /&gt;
&lt;br /&gt;
   enable_ints();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
or in [[assembly]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;br /&gt;
;;&lt;br /&gt;
;; NASM 32bit assembler&lt;br /&gt;
;;&lt;br /&gt;
&lt;br /&gt;
[bits 32]&lt;br /&gt;
[section .text]&lt;br /&gt;
&lt;br /&gt;
enable_A20:&lt;br /&gt;
        cli&lt;br /&gt;
&lt;br /&gt;
        call    a20wait&lt;br /&gt;
        mov     al,0xAD&lt;br /&gt;
        out     0x64,al&lt;br /&gt;
&lt;br /&gt;
        call    a20wait&lt;br /&gt;
        mov     al,0xD0&lt;br /&gt;
        out     0x64,al&lt;br /&gt;
&lt;br /&gt;
        call    a20wait2&lt;br /&gt;
        in      al,0x60&lt;br /&gt;
        push    eax&lt;br /&gt;
&lt;br /&gt;
        call    a20wait&lt;br /&gt;
        mov     al,0xD1&lt;br /&gt;
        out     0x64,al&lt;br /&gt;
&lt;br /&gt;
        call    a20wait&lt;br /&gt;
        pop     eax&lt;br /&gt;
        or      al,2&lt;br /&gt;
        out     0x60,al&lt;br /&gt;
&lt;br /&gt;
        call    a20wait&lt;br /&gt;
        mov     al,0xAE&lt;br /&gt;
        out     0x64,al&lt;br /&gt;
&lt;br /&gt;
        call    a20wait&lt;br /&gt;
        sti&lt;br /&gt;
        ret&lt;br /&gt;
&lt;br /&gt;
a20wait:&lt;br /&gt;
        in      al,0x64&lt;br /&gt;
        test    al,2&lt;br /&gt;
        jnz     a20wait&lt;br /&gt;
        ret&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
a20wait2:&lt;br /&gt;
        in      al,0x64&lt;br /&gt;
        test    al,1&lt;br /&gt;
        jz      a20wait2&lt;br /&gt;
        ret&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Fast A20 Gate===&lt;br /&gt;
在大多数以IBM PS/2开始的较新计算机上，芯片组有一个FAST A20选项，可以快速启用A20线路设置。 如果以这种方式启用A20，则不需要延迟循环或轮询，只需3条简单的指令。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;br /&gt;
in al, 0x92&lt;br /&gt;
or al, 2&lt;br /&gt;
out 0x92, al&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
正如在 [http://www.win.tue.nl/~ aeb/linux/kbd/A20.html 参见站点]中提到的，最好仅在必要时进行写入，并确保位0为0，因为它用于快速重置。 下面是一个例子：&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;br /&gt;
in al, 0x92&lt;br /&gt;
test al, 2&lt;br /&gt;
jnz after&lt;br /&gt;
or al, 2&lt;br /&gt;
and al, 0xFE&lt;br /&gt;
out 0x92, al&lt;br /&gt;
after:&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
然而，并非所有地方都支持Fast A20方法，而且没有可靠的方法来判断它是否会对给定的系统产生一些影响。 更糟糕的是，在某些系统上，它实际上可能会做其他事情，例如清空屏幕，因此只有在 [[BIOS]] 报告FAST A20可用后才应使用它。 还需要为缺乏FAST A20支持的系统编写代码，因此不鼓励只依赖这种方法。 此外，在某些芯片组上，你可能需要在BIOS配置屏幕中启用Fast A20支持。&lt;br /&gt;
&lt;br /&gt;
===INT 15===&lt;br /&gt;
另一种方法是使用BIOS。&lt;br /&gt;
&amp;lt;source lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;br /&gt;
;FASM&lt;br /&gt;
use16&lt;br /&gt;
mov     ax,2403h                ;--- A20-Gate Support ---&lt;br /&gt;
int     15h&lt;br /&gt;
jb      a20_ns                  ;INT 15h is not supported&lt;br /&gt;
cmp     ah,0&lt;br /&gt;
jnz     a20_ns                  ;INT 15h is not supported&lt;br /&gt;
&lt;br /&gt;
mov     ax,2402h                ;--- A20-Gate Status ---&lt;br /&gt;
int     15h&lt;br /&gt;
jb      a20_failed              ;couldn't get status&lt;br /&gt;
cmp     ah,0&lt;br /&gt;
jnz     a20_failed              ;couldn't get status&lt;br /&gt;
&lt;br /&gt;
cmp     al,1&lt;br /&gt;
jz      a20_activated           ;A20 is already activated&lt;br /&gt;
&lt;br /&gt;
mov     ax,2401h                ;--- A20-Gate Activate ---&lt;br /&gt;
int     15h&lt;br /&gt;
jb      a20_failed              ;couldn't activate the gate&lt;br /&gt;
cmp     ah,0&lt;br /&gt;
jnz     a20_failed              ;couldn't activate the gate&lt;br /&gt;
&lt;br /&gt;
a20_activated:                  ;go on&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
如果有一个中断失败，你将不得不使用另一种方法。（见下文。）&lt;br /&gt;
&lt;br /&gt;
===访问0xee===&lt;br /&gt;
在某些系统上，读取IO端口 0xee启用A20，而写入则禁用A20。 （或者，有时，此操作仅在启用IO端口 0xee时发生。） 类似的情况也适用于IO端口 0xef和Reset(写入会导致重置)。&lt;br /&gt;
来自i386SL/i486SL文档：&lt;br /&gt;
&lt;br /&gt;
以下端口仅在启用时可见，对这些端口的任何写入都会导致对应名称的操作。&lt;br /&gt;
&amp;lt;pre&amp;gt;Name of Register     Address   Default Value  Where placed    Size&lt;br /&gt;
FAST CPU RESET         EFh          N/A         82360SL         8&lt;br /&gt;
FAST A20 GATE          EEh          N/A         82360SL         8  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;启用A20：&lt;br /&gt;
&amp;lt;source lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;br /&gt;
in al,0xee&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
禁用A20:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;br /&gt;
out 0xee,al&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''注意''' 写入时AL包含什么并不重要，读取时AL未定义（端口0xee）&lt;br /&gt;
&lt;br /&gt;
=== 推荐方法 ===&lt;br /&gt;
&lt;br /&gt;
因为有几种不同的方法可能被支持，也可能不被支持，而且其中一些方法会在某些计算机上引发问题； 推荐的方法是按“风险最小”的顺序尝试所有这些方法，直到其中一种方法起作用。 本质上:&lt;br /&gt;
* 测试A20是否已启用——如果已启用，则根本不需要执行任何操作&lt;br /&gt;
* 尝试使用BIOS功能。  忽略返回状态。&lt;br /&gt;
* 测试A20是否启用（查看BIOS功能是否实际工作）&lt;br /&gt;
* 尝试键盘控制器方法。&lt;br /&gt;
* 测试是否在循环中启用了A20并具有超时等待-(因为键盘控制器方法可能工作缓慢)&lt;br /&gt;
* 最后尝试Fast A20方法&lt;br /&gt;
* 测试A20是否在超时循环中启用(因为FAST A20方法可能工作缓慢)&lt;br /&gt;
* 如果以上都不起作用，请放弃&lt;br /&gt;
&lt;br /&gt;
==另见==&lt;br /&gt;
===外部链接===&lt;br /&gt;
*http://www.win.tue.nl/~aeb/linux/kbd/A20.html&lt;br /&gt;
&lt;br /&gt;
[[Category:X86]]&lt;br /&gt;
[[de:A20-Gate]]&lt;/div&gt;</summary>
		<author><name>Zhang3</name></author>
	</entry>
</feed>