<?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=GDT_Tutorial</id>
	<title>GDT Tutorial - 版本历史</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.foofun.cn//index.php?action=history&amp;feed=atom&amp;title=GDT_Tutorial"/>
	<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=GDT_Tutorial&amp;action=history"/>
	<updated>2026-04-05T05:24:28Z</updated>
	<subtitle>本wiki上该页面的版本历史</subtitle>
	<generator>MediaWiki 1.37.1</generator>
	<entry>
		<id>http://wiki.foofun.cn//index.php?title=GDT_Tutorial&amp;diff=735&amp;oldid=prev</id>
		<title>2022年3月7日 (一) 14:01 Zhang3</title>
		<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=GDT_Tutorial&amp;diff=735&amp;oldid=prev"/>
		<updated>2022-03-07T14:01:56Z</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年3月7日 (一) 14:01的版本&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-l1&quot;&gt;第1行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第1行：&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;{{Rating|1}}&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;{{Rating|1}}&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;在 [[IA32_Architecture_Family|IA-32]] 和 [[X86-64|x86-64]] 架构上，更准确地说，在 '''[[Protected Mode|保护模式-Protected Mode]]''' 或 '''[[Long Mode|长模式-Long Mode]]''' 中，控制[[Interrupt Service Routines|中断服务例程 ISR-Interrupt Service Routines]] 和做好[[memory management|内存管理]]&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;都需要通过描述符（descriptors）表。 &lt;/del&gt;每个描述符存储CPU在某个时间点可能需要的单个目标（例如服务例程、任务、代码或数据块）信息。 例如，如果你尝试将新值加载到'''[[Segmentation|段寄存器]]'''中时， CPU需要执行安全和访问控制检查，以查看你是否实际上有权访问该特定内存区域。 一旦执行了检查，有用的值（如最低和最高地址）就会根据描述符，被读取并缓存到也许不可见的CPU寄存器中。&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;在 [[IA32_Architecture_Family|IA-32]] 和 [[X86-64|x86-64]] 架构上，更准确地说，在 '''[[Protected Mode|保护模式-Protected Mode]]''' 或 '''[[Long Mode|长模式-Long Mode]]''' 中，控制[[Interrupt Service Routines|中断服务例程 ISR-Interrupt Service Routines]] 和做好[[memory management|内存管理]]&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;都需要通过描述符表（descriptors table）。 &lt;/ins&gt;每个描述符存储CPU在某个时间点可能需要的单个目标（例如服务例程、任务、代码或数据块）信息。 例如，如果你尝试将新值加载到'''[[Segmentation|段寄存器]]'''中时， CPU需要执行安全和访问控制检查，以查看你是否实际上有权访问该特定内存区域。 一旦执行了检查，有用的值（如最低和最高地址）就会根据描述符，被读取并缓存到也许不可见的CPU寄存器中。&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;在这些体系结构上，有三种此类型的表：'''[[Global Descripptor Table|全局描述符表-Global Descripptor Table]]'''、'''[[Local DescrippTable|&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;本地描述符表_Local &lt;/del&gt;DescrippTable]]'''和'''[[Interrupt Descriptor Table|中断描述符表]]'''(它取代了'''[Interrupt Vector Table|中断向量表-Interrupt Vector Table]]''')。 上面每个表都用它们的大小和 '''[[linear address|线性地址]]'''进行了定义， 并分别通过 '''LGDT'''、'''LLDT''' 和'''LIDT''' 指令发送到CPU。 在几乎所有的用例中，这些表都只在启动时放入内存一次，然后在需要时进行编辑。&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;在这些体系结构上，有三种此类型的表：'''[[Global Descripptor Table|全局描述符表-Global Descripptor Table]]'''、'''[[Local DescrippTable|&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;本地描述符表-Local &lt;/ins&gt;DescrippTable]]'''和'''[[Interrupt Descriptor Table|中断描述符表]]'''(它取代了'''&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[&lt;/ins&gt;[Interrupt Vector Table|中断向量表-Interrupt Vector Table]]''')。 上面每个表都用它们的大小和 '''[[linear address|线性地址]]'''进行了定义， 并分别通过 '''LGDT'''、'''LLDT''' 和'''LIDT''' 指令发送到CPU。 在几乎所有的用例中，这些表都只在启动时放入内存一次，然后在需要时进行编辑。&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-l29&quot;&gt;第29行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第29行：&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;=== Flat / Long Mode 设置===&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;=== Flat / Long Mode 设置===&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;如果你不希望使用'''[[Segmentation|分段]]'''将内存分隔为多个受保护区域，则只需使用几个段描述符即可。 一个原因可能是你希望仅使用分页来保护内存。 此外，此设置方式在'''[[Long Mode&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;]&lt;/del&gt;]]'''中必须'''严格执行'''，因为base和limit值已经被忽略了。&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;如果你不希望使用'''[[Segmentation|分段]]'''将内存分隔为多个受保护区域，则只需使用几个段描述符即可。 一个原因可能是你希望仅使用分页来保护内存。 此外，此设置方式在'''[[Long Mode]]'''中必须'''严格执行'''，因为base和limit值已经被忽略了。&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;在此方案中，唯一需要的'''[[Global_Descriptor_Table#段描述符（Segment_Descriptor）|段描述符-Segment Descriptor]]'''是'''空描述符'''， 以及一个描述符(由期望的特权级别、段类型和执行模式的组合而成)，以及系统描述符。 通常，这将包括内核和用户模式的一个代码段和一个数据段，以及一个'''[[Task State Segment]]'''。&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;在此方案中，唯一需要的'''[[Global_Descriptor_Table#段描述符（Segment_Descriptor）|段描述符-Segment Descriptor]]'''是'''空描述符'''， 以及一个描述符(由期望的特权级别、段类型和执行模式的组合而成)，以及系统描述符。 通常，这将包括内核和用户模式的一个代码段和一个数据段，以及一个'''[[Task State Segment]]'''。&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-l119&quot;&gt;第119行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第119行：&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;&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;如果启用了中断，则 &lt;/del&gt;“绝对确定” 将其关闭，否则你可能会遇到不希望的行为和异常。 这可以通过'''CLI'''汇编指令实现。&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;“绝对确定” 将其关闭，否则你可能会遇到不希望的行为和异常。 这可以通过'''CLI'''汇编指令实现。&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 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;上面的 '''GDT''' 结构说明中还没有向你展示如何以正确的格式编写条目。 由于与286的'''GDT'''向后兼容，描述符的实际结构有点混乱。 &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Base地址分为三个不同的字段，并且你不能对随意选择limit进行编码。&lt;/del&gt;&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;上面的 '''GDT''' 结构说明中还没有向你展示如何以正确的格式编写条目。 由于与286的'''GDT'''向后兼容，描述符的实际结构有点混乱。 &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Base地址分为三个不同的字段，并且你不能对随意选择的limit进行编码。&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;c&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;c&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-l152&quot;&gt;第152行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第152行：&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;为了填写GDT表，你需要为每个条目使用一次此函数，这里&amp;lt;tt&amp;gt;*target&amp;lt;/tt&amp;gt;指向'''Segment Descriptor'''的逻辑地址，&amp;lt;tt&amp;gt;source&amp;lt;/tt&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;为了填写GDT表，你需要为每个条目使用一次此函数，这里&amp;lt;tt&amp;gt;*target&amp;lt;/tt&amp;gt;指向'''Segment Descriptor'''的逻辑地址，&amp;lt;tt&amp;gt;source&amp;lt;/tt&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;当然，你也可以在 '''GDT'''&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;源结构体 &lt;/del&gt;中对值实现进行硬编码，而不是在运行时转换它们。&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;当然，你也可以在 '''GDT'''&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;source结构体 &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;=== 告诉CPU表在哪里===&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;=== 告诉CPU表在哪里===&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-l181&quot;&gt;第181行：&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;第181行：&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;==== Protected Mode, Flat Model ====&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;==== Protected Mode, Flat Model ====&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;“Flat”表示数据段的基地址为0(无论是否启用了'''[[Paging]]''')。 例如，如果你的代码刚刚被 [[GRUB]] 引导，就是这种情况。 在'''[[System V ABI]]'''中，参数在堆栈中按相反顺序传递，因此可以&amp;lt;tt&amp;gt;setGdt(limit, base)&amp;lt;/tt&amp;gt;的函数调用可能类似于以下示例代码。&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;“Flat”表示数据段的基地址为0(无论是否启用了'''[[Paging&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;|分页&lt;/ins&gt;]]''')。 例如，如果你的代码刚刚被 [[GRUB]] 引导，就是这种情况。 在'''[[System V ABI]]'''中，参数在堆栈中按相反顺序传递，因此可以&amp;lt;tt&amp;gt;setGdt(limit, base)&amp;lt;/tt&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;&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=GDT_Tutorial&amp;diff=728&amp;oldid=prev</id>
		<title>2022年3月7日 (一) 06:23 Zhang3</title>
		<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=GDT_Tutorial&amp;diff=728&amp;oldid=prev"/>
		<updated>2022-03-07T06:23:14Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;http://wiki.foofun.cn//index.php?title=GDT_Tutorial&amp;amp;diff=728&amp;amp;oldid=258&quot;&gt;显示更改&lt;/a&gt;</summary>
		<author><name>Zhang3</name></author>
	</entry>
	<entry>
		<id>http://wiki.foofun.cn//index.php?title=GDT_Tutorial&amp;diff=258&amp;oldid=prev</id>
		<title>Zhang3：创建页面，内容为“{{Rating|1}} 在  Intel Architecture 中，更确切地说，在 protected mode 中，大多数 memory management 和 Interrupt Service Routines 都是通过描述符表来控制的。 每个描述符存储关于CPU在某个时间可能需要的单个对象 (例如，服务例程、任务、代码或数据块，无论什么) 的信息。 例如，如果您尝试将新值加载到  段寄存器 中，则CPU需要执行…”</title>
		<link rel="alternate" type="text/html" href="http://wiki.foofun.cn//index.php?title=GDT_Tutorial&amp;diff=258&amp;oldid=prev"/>
		<updated>2022-01-20T03:27:15Z</updated>

		<summary type="html">&lt;p&gt;创建页面，内容为“{{Rating|1}} 在 &lt;a href=&quot;/index.php?title=%E5%88%86%E7%B1%BB:X86&quot; title=&quot;分类:X86&quot;&gt; Intel Architecture&lt;/a&gt; 中，更确切地说，在 &lt;a href=&quot;/index.php?title=Protected_mode&quot; class=&quot;mw-redirect&quot; title=&quot;Protected mode&quot;&gt;protected mode&lt;/a&gt; 中，大多数 &lt;a href=&quot;/index.php?title=Memory_management&quot; title=&quot;Memory management&quot;&gt;memory management&lt;/a&gt; 和 &lt;a href=&quot;/index.php?title=Interrupt_Service_Routines&quot; title=&quot;Interrupt Service Routines&quot;&gt;Interrupt Service Routines&lt;/a&gt; 都是通过描述符表来控制的。 每个描述符存储关于CPU在某个时间可能需要的单个对象 (例如，服务例程、任务、代码或数据块，无论什么) 的信息。 例如，如果您尝试将新值加载到 &lt;a href=&quot;/index.php?title=Segment&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;Segment（页面不存在）&quot;&gt; 段寄存器&lt;/a&gt; 中，则CPU需要执行…”&lt;/p&gt;
&lt;p&gt;&lt;b&gt;新页面&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Rating|1}}&lt;br /&gt;
在 [[:Category:x86 | Intel Architecture]] 中，更确切地说，在 [[protected mode]] 中，大多数 [[memory management]] 和 [[Interrupt Service Routines]] 都是通过描述符表来控制的。 每个描述符存储关于CPU在某个时间可能需要的单个对象 (例如，服务例程、任务、代码或数据块，无论什么) 的信息。 例如，如果您尝试将新值加载到 [[Segment | 段寄存器]] 中，则CPU需要执行安全和访问控制检查，以查看您是否实际上有权访问该特定内存区域。 一旦执行了检查，有用的值 (例如最低和最高地址) 就会缓存在CPU的不可见寄存器中。&lt;br /&gt;
&lt;br /&gt;
英特尔定义了3种类型的表: [[Interrupt Descriptor Table]] (取代 [[IVT]]) 、全局描述符表 ([[GDT]]) 和本地描述符表。 每个表分别通过 &amp;lt;tt&amp;gt;LIDT&amp;lt;/tt&amp;gt;，&amp;lt;tt&amp;gt;LGDT&amp;lt;/tt&amp;gt;，&amp;lt;tt&amp;gt;LLDT&amp;lt;/tt&amp;gt; 指令定义为 (大小，[[线性地址]]) 到CPU。 在大多数情况下，操作系统只是在启动时告诉这些表的位置，然后简单地通过指针写入/读取表。&lt;br /&gt;
&lt;br /&gt;
== 词汇表 ==&lt;br /&gt;
&lt;br /&gt;
; Segment&lt;br /&gt;
: 具有一致属性的逻辑上连续的内存块 (CPU的说法)&lt;br /&gt;
; Segment Register&lt;br /&gt;
: 您的CPU的寄存器，它引用了用于特殊用途的段 (例如 &amp;lt;tt&amp;gt;SS&amp;lt;/tt&amp;gt;，&amp;lt;tt&amp;gt;CS&amp;lt;/tt&amp;gt;，&amp;lt;tt&amp;gt;DS&amp;lt;/tt&amp;gt; ...)&lt;br /&gt;
; Selector&lt;br /&gt;
: 对可以加载到段寄存器中的描述符的引用; 选择器是描述符表项的偏移量。 这些条目有8个字节长。 因此，位3及以上仅声明描述符表条目偏移，而位2指定此选择器是GDT还是LDT选择器 (LDT位设置，GDT位清除)，和位0-1声明需要对应描述符表项的DPL字段的Ring级。 如果没有，则发生一般保护故障; 如果确实对应，则相应地更改所用选择器的CPL级别。&lt;br /&gt;
; Descriptor&lt;br /&gt;
: 告诉CPU给定段的属性的内存结构 (表的一部分)&lt;br /&gt;
&lt;br /&gt;
= = 在GDT里放什么 = =&lt;br /&gt;
&lt;br /&gt;
=== 基础 ===&lt;br /&gt;
&lt;br /&gt;
出于理智的目的，您应该始终将这些项目存储在GDT中:&lt;br /&gt;
&lt;br /&gt;
* 处理器从未引用的空描述符。 某些仿真器 (例如Bochs) 会抱怨如果您没有出现限制异常。 有些使用此描述符来存储指向GDT本身的指针 (与LGDT指令一起使用)。 空描述符是8字节宽，指针是6字节宽，所以它可能只是这个完美的地方。&lt;br /&gt;
* 一个代码段描述符 (对于您的内核，它应该具有type = 0x9A)&lt;br /&gt;
* 数据段描述符 (您不能写入代码段，因此请使用type = 0x92添加它)&lt;br /&gt;
* [[TSS]] 段描述符 (相信我，至少保留一个位置)&lt;br /&gt;
* 如果需要，可以容纳更多细分段 (例如用户级别，[[LDT]]，更多ts，等等)&lt;br /&gt;
&lt;br /&gt;
=== Sysenter/Sysexit ===&lt;br /&gt;
&lt;br /&gt;
如果您使用的是Intel &amp;lt;tt&amp;gt;SYSENTER&amp;lt;/tt&amp;gt;/&amp;lt;tt&amp;gt;SYSEXIT&amp;lt;/tt&amp;gt; 例程，则GDT的结构必须如下:&lt;br /&gt;
&lt;br /&gt;
* 前面的任何描述符 (空描述符、特殊内核的东西等)&lt;br /&gt;
* 一个 [[DPL]] 0代码段描述符 (&amp;lt;tt&amp;gt;SYSENTER&amp;lt;/tt&amp;gt; 将使用的那个)&lt;br /&gt;
* 一个DPL 0数据段描述符 (用于 &amp;lt;tt&amp;gt;SYSENTER&amp;lt;/tt&amp;gt; 堆栈)&lt;br /&gt;
* DPL 3代码段 (用于 &amp;lt;tt&amp;gt;SYSEXIT&amp;lt;/tt&amp;gt; 之后的代码)&lt;br /&gt;
* DPL 3数据段 (用于 &amp;lt;tt&amp;gt;SYSEXIT&amp;lt;/tt&amp;gt; 之后的用户模式堆栈)&lt;br /&gt;
* 任何其他描述符&lt;br /&gt;
&lt;br /&gt;
DPL 0代码段的段被加载到 [[MSR]] 中。 其他的是根据该值计算的。 有关更多信息，请参阅 &amp;lt;tt&amp;gt;SYSENTER&amp;lt;/tt&amp;gt; 和 &amp;lt;tt&amp;gt;SYSEXIT&amp;lt;/tt&amp;gt; 的英特尔说明参考。&lt;br /&gt;
&lt;br /&gt;
您存储在那里的实际值将取决于您的系统设计。&lt;br /&gt;
&lt;br /&gt;
=== Flat设置 ===&lt;br /&gt;
&lt;br /&gt;
您想要完整的4个GiB地址未翻译: 只需使用&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
GDT[0] = {.base=0, .limit=0, .type=0};                     // Selector 0x00 cannot be used&lt;br /&gt;
GDT[1] = {.base=0, .limit=0xffffffff, .type=0x9A};         // Selector 0x08 will be our code&lt;br /&gt;
GDT[2] = {.base=0, .limit=0xffffffff, .type=0x92};         // Selector 0x10 will be our data&lt;br /&gt;
GDT[3] = {.base=&amp;amp;myTss, .limit=sizeof(myTss), .type=0x89}; // You can use LTR(0x18)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
请注意，在此模型中，由于代码和数据段重叠，因此实际上并未保护代码免受覆盖。&lt;br /&gt;
&lt;br /&gt;
= = 小内核设置 = =&lt;br /&gt;
&lt;br /&gt;
如果您希望 (出于特定原因) 将代码和数据清楚地分开 (假设两者都有4 MiB，也从4 MiB开始)，只需使用:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
GDT[0] = {.base=0, .limit=0, .type=0};                      // Selector 0x00 cannot be used&lt;br /&gt;
GDT[1] = {.base=0x400000, .limit=0x3fffff, .type=0x9A}; // Selector 0x08 will be our code&lt;br /&gt;
GDT[2] = {.base=0x800000, .limit=0x3fffff, .type=0x92}; // Selector 0x10 will be our data&lt;br /&gt;
GDT[3] = {.base=&amp;amp;myTss, .limit=sizeof(myTss), .type=0x89};  // You can use LTR(0x18)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
这意味着您在物理地址4 MiB加载的任何内容都将在 &amp;lt;tt&amp;gt;CS:0&amp;lt;/tt&amp;gt; 处显示为代码，而您在物理地址8 MiB加载的内容将在 &amp;lt;tt&amp;gt;DS:0&amp;lt;/tt&amp;gt; 处显示为数据。 然而，这可能不是最好的设计。&lt;br /&gt;
&lt;br /&gt;
= = 怎么做 = =&lt;br /&gt;
&lt;br /&gt;
=== 禁用中断 ===&lt;br /&gt;
&lt;br /&gt;
如果启用了它们，请将其关闭，否则您将遇到麻烦。&lt;br /&gt;
&lt;br /&gt;
=== 填表 ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;GDT[]&amp;lt;/tt&amp;gt; 的上述结构并不完整。 对于向后兼容286的GDT，描述符的实际结构有点混乱。 基址在3个不同的字段上分割，您不能编码任何您想要的限制。 另外，在这里和那里，如果你想让事情正常工作，你需要正确设置这些标志。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 * \param target A pointer to the 8-byte GDT entry&lt;br /&gt;
 * \param source An arbitrary structure describing the GDT entry&lt;br /&gt;
 */&lt;br /&gt;
void encodeGdtEntry(uint8_t *target, struct GDT source)&lt;br /&gt;
{&lt;br /&gt;
    // Check the limit to make sure that it can be encoded&lt;br /&gt;
    if ((source.limit &amp;gt; 65536) &amp;amp;&amp;amp; ((source.limit &amp;amp; 0xFFF) != 0xFFF)) {&lt;br /&gt;
        kerror(&amp;quot;You can't do that!&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
    if (source.limit &amp;gt; 65536) {&lt;br /&gt;
        // Adjust granularity if required&lt;br /&gt;
        source.limit = source.limit &amp;gt;&amp;gt; 12;&lt;br /&gt;
        target[6] = 0xC0;&lt;br /&gt;
    } else {&lt;br /&gt;
        target[6] = 0x40;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    // Encode the limit&lt;br /&gt;
    target[0] = source.limit &amp;amp; 0xFF;&lt;br /&gt;
    target[1] = (source.limit &amp;gt;&amp;gt; 8) &amp;amp; 0xFF;&lt;br /&gt;
    target[6] |= (source.limit &amp;gt;&amp;gt; 16) &amp;amp; 0xF;&lt;br /&gt;
    &lt;br /&gt;
    // Encode the base &lt;br /&gt;
    target[2] = source.base &amp;amp; 0xFF;&lt;br /&gt;
    target[3] = (source.base &amp;gt;&amp;gt; 8) &amp;amp; 0xFF;&lt;br /&gt;
    target[4] = (source.base &amp;gt;&amp;gt; 16) &amp;amp; 0xFF;&lt;br /&gt;
    target[7] = (source.base &amp;gt;&amp;gt; 24) &amp;amp; 0xFF;&lt;br /&gt;
    &lt;br /&gt;
    // And... Type&lt;br /&gt;
    target[5] = source.type;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
当然，您可以对其进行硬编码，而不是在运行时将其转换。 此代码假定您只需要32位段。&lt;br /&gt;
&lt;br /&gt;
=== 告诉CPU表的位置 ===&lt;br /&gt;
&lt;br /&gt;
这里需要一些汇编示例。 虽然您可以使用 [[内联程序集]]，但 &amp;lt;tt&amp;gt;LGDT&amp;lt;/tt&amp;gt; 和 &amp;lt;tt&amp;gt;LIDT&amp;lt;/tt&amp;gt; 所期望的内存打包使编写小型程序集例程变得更加容易。 如上所述，您将使用 &amp;lt;tt&amp;gt;LGDT&amp;lt;/tt&amp;gt; 指令加载基地址和GDT的限制。 由于基址应该是一个线性地址，因此您需要根据当前的 [[MMU]] 设置进行一些调整。&lt;br /&gt;
&lt;br /&gt;
==== 从实模 ====&lt;br /&gt;
&lt;br /&gt;
此处的线性地址应计算为 &amp;lt;tt&amp;gt; 段 * 16偏移 &amp;lt;/tt&amp;gt;。 &amp;lt;tt&amp;gt;GDT&amp;lt;/tt&amp;gt; 和 &amp;lt;tt&amp;gt;GDT_end&amp;lt;/tt&amp;gt; 被假定为当前数据段中的符号。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;br /&gt;
gdtr DW 0 ; For limit storage&lt;br /&gt;
     DD 0 ; For base storage&lt;br /&gt;
&lt;br /&gt;
setGdt:&lt;br /&gt;
   XOR   EAX, EAX&lt;br /&gt;
   MOV   AX, DS&lt;br /&gt;
   SHL   EAX, 4&lt;br /&gt;
   ADD   EAX, ''GDT''&lt;br /&gt;
   MOV   [gdtr + 2], eax&lt;br /&gt;
   MOV   EAX, ''GDT_end''&lt;br /&gt;
   SUB   EAX, ''GDT''&lt;br /&gt;
   MOV   [gdtr], AX&lt;br /&gt;
   LGDT  [gdtr]&lt;br /&gt;
   RET&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 从平面，保护模式 ====&lt;br /&gt;
&lt;br /&gt;
“Flat” 表示数据段的基数为0 (无论分页是打开还是关闭)。 例如，如果您只是被 [[GRUB]] 引导，情况就是这样。 您应该将其称为 &amp;lt;tt&amp;gt;setGdt(GDT，sizeof(GDT))&amp;lt;/tt&amp;gt;。&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;br /&gt;
gdtr DW 0 ; For limit storage&lt;br /&gt;
     DD 0 ; For base storage&lt;br /&gt;
&lt;br /&gt;
setGdt:&lt;br /&gt;
   MOV   EAX, [esp + 4]&lt;br /&gt;
   MOV   [gdtr + 2], EAX&lt;br /&gt;
   MOV   AX, [ESP + 8]&lt;br /&gt;
   DEC   AX&lt;br /&gt;
   MOV   [gdtr], AX&lt;br /&gt;
   LGDT  [gdtr]&lt;br /&gt;
   RET&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 来自非flat保护模式 ====&lt;br /&gt;
&lt;br /&gt;
如果您的数据段具有非零基数 (例如，您在分段技巧中使用的是 [[较高的半内核]])， 您必须在上面序列的 “&amp;lt;tt&amp;gt;MOV EAX，...&amp;lt;/tt&amp;gt;” 和 “&amp;lt;tt&amp;gt;MOV...，EAX&amp;lt;/tt&amp;gt;” 指令之间 “&amp;lt;tt&amp;gt; 添加EAX，base_of_your_data_segment_which_you_should_know&amp;lt;/tt&amp;gt;”。&lt;br /&gt;
&lt;br /&gt;
=== 重新加载段寄存器 ===&lt;br /&gt;
&lt;br /&gt;
无论您对GDT做什么，都不会对CPU产生影响，直到您将选择器加载到段寄存器中。 您可以使用以下方法执行此操作:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;asm&amp;quot;&amp;gt;&lt;br /&gt;
reloadSegments:&lt;br /&gt;
   ; Reload CS register containing code selector:&lt;br /&gt;
   JMP   0x08:.reload_CS ; 0x08 points at the new code selector&lt;br /&gt;
.reload_CS:&lt;br /&gt;
   ; Reload data segment registers:&lt;br /&gt;
   MOV   AX, 0x10 ; 0x10 points at the new data selector&lt;br /&gt;
   MOV   DS, AX&lt;br /&gt;
   MOV   ES, AX&lt;br /&gt;
   MOV   FS, AX&lt;br /&gt;
   MOV   GS, AX&lt;br /&gt;
   MOV   SS, AX&lt;br /&gt;
   RET&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
可以找到上述代码的解释 [http://stackoverflow.com/questions/23978486/far-jump-in-gdt-in-bootloader here]。&lt;br /&gt;
&lt;br /&gt;
== LDT ==&lt;br /&gt;
&lt;br /&gt;
与GDT (全局描述符表) 非常相似，LDT (“本地” 描述符表) 包含用于内存段描述，调用门等的描述符。 LDT的好处是，每个任务都可以有自己的LDT，并且当您使用硬件任务切换时，处理器会自动切换到正确的LDT。&lt;br /&gt;
&lt;br /&gt;
由于其内容在每个任务中可能不同，因此LDT不是放置系统内容 (例如TSS或其他LDT描述符) 的合适位置: 这些是GDT的唯一特别之处。 由于要经常更改，因此用于加载LDT的命令与GDT和IDT加载有点不同。 这些参数不是直接给出LDT的基地址和大小，而是存储在GDT的描述符中 (具有适当的 “LDT” 类型)，并给出该条目的选择器。&lt;br /&gt;
&lt;br /&gt;
                GDTR (base + limit)&lt;br /&gt;
               +-- GDT ------------+&lt;br /&gt;
               |                   |&lt;br /&gt;
 SELECTOR ---&amp;gt; [LDT descriptor     ]----&amp;gt; LDTR (base + limit)&lt;br /&gt;
               |                   |     +-- LDT ------------+&lt;br /&gt;
               |                   |     |                   |&lt;br /&gt;
              ...                 ...   ...                 ...&lt;br /&gt;
               +-------------------+     +-------------------+&lt;br /&gt;
&lt;br /&gt;
请注意，使用386处理器，分页使LDT几乎过时，并且不再需要多个LDT描述符，因此您几乎可以安全地忽略LDT进行操作系统开发，除非您设计了许多不同的段来存储。&lt;br /&gt;
&lt;br /&gt;
== The IDT and why it's needed ==&lt;br /&gt;
&lt;br /&gt;
如上所述，IDT (中断描述符表) 的加载方式与GDT大致相同，其结构大致相同，只是它只包含门而不包含段。 每个门给出了对一段代码 (代码段、权限级别和该段中的代码的偏移量) 的完整引用，该代码现在绑定到0和255之间的数字 (IDT中的时隙)。&lt;br /&gt;
&lt;br /&gt;
IDT将是在内核序列中启用的第一件事，以便您可以捕获硬件异常，侦听外部事件等。 有关X86系列中断的更多信息，请参见 [[中断]]。&lt;br /&gt;
&lt;br /&gt;
== 一些让你的生活变得轻松的东西 ==&lt;br /&gt;
&lt;br /&gt;
轻松创建GDT条目的工具。&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Used for creating GDT segment descriptors in 64-bit integer form.&lt;br /&gt;
 &lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
// Each define here is for a specific flag in the descriptor.&lt;br /&gt;
// Refer to the intel documentation for a description of what each one does.&lt;br /&gt;
#define SEG_DESCTYPE(x)  ((x) &amp;lt;&amp;lt; 0x04) // Descriptor type (0 for system, 1 for code/data)&lt;br /&gt;
#define SEG_PRES(x)      ((x) &amp;lt;&amp;lt; 0x07) // Present&lt;br /&gt;
#define SEG_SAVL(x)      ((x) &amp;lt;&amp;lt; 0x0C) // Available for system use&lt;br /&gt;
#define SEG_LONG(x)      ((x) &amp;lt;&amp;lt; 0x0D) // Long mode&lt;br /&gt;
#define SEG_SIZE(x)      ((x) &amp;lt;&amp;lt; 0x0E) // Size (0 for 16-bit, 1 for 32)&lt;br /&gt;
#define SEG_GRAN(x)      ((x) &amp;lt;&amp;lt; 0x0F) // Granularity (0 for 1B - 1MB, 1 for 4KB - 4GB)&lt;br /&gt;
#define SEG_PRIV(x)     (((x) &amp;amp;  0x03) &amp;lt;&amp;lt; 0x05)   // Set privilege level (0 - 3)&lt;br /&gt;
 &lt;br /&gt;
#define SEG_DATA_RD        0x00 // Read-Only&lt;br /&gt;
#define SEG_DATA_RDA       0x01 // Read-Only, accessed&lt;br /&gt;
#define SEG_DATA_RDWR      0x02 // Read/Write&lt;br /&gt;
#define SEG_DATA_RDWRA     0x03 // Read/Write, accessed&lt;br /&gt;
#define SEG_DATA_RDEXPD    0x04 // Read-Only, expand-down&lt;br /&gt;
#define SEG_DATA_RDEXPDA   0x05 // Read-Only, expand-down, accessed&lt;br /&gt;
#define SEG_DATA_RDWREXPD  0x06 // Read/Write, expand-down&lt;br /&gt;
#define SEG_DATA_RDWREXPDA 0x07 // Read/Write, expand-down, accessed&lt;br /&gt;
#define SEG_CODE_EX        0x08 // Execute-Only&lt;br /&gt;
#define SEG_CODE_EXA       0x09 // Execute-Only, accessed&lt;br /&gt;
#define SEG_CODE_EXRD      0x0A // Execute/Read&lt;br /&gt;
#define SEG_CODE_EXRDA     0x0B // Execute/Read, accessed&lt;br /&gt;
#define SEG_CODE_EXC       0x0C // Execute-Only, conforming&lt;br /&gt;
#define SEG_CODE_EXCA      0x0D // Execute-Only, conforming, accessed&lt;br /&gt;
#define SEG_CODE_EXRDC     0x0E // Execute/Read, conforming&lt;br /&gt;
#define SEG_CODE_EXRDCA    0x0F // Execute/Read, conforming, accessed&lt;br /&gt;
 &lt;br /&gt;
#define GDT_CODE_PL0 SEG_DESCTYPE(1) | SEG_PRES(1) | SEG_SAVL(0) | \&lt;br /&gt;
                     SEG_LONG(0)     | SEG_SIZE(1) | SEG_GRAN(1) | \&lt;br /&gt;
                     SEG_PRIV(0)     | SEG_CODE_EXRD&lt;br /&gt;
 &lt;br /&gt;
#define GDT_DATA_PL0 SEG_DESCTYPE(1) | SEG_PRES(1) | SEG_SAVL(0) | \&lt;br /&gt;
                     SEG_LONG(0)     | SEG_SIZE(1) | SEG_GRAN(1) | \&lt;br /&gt;
                     SEG_PRIV(0)     | SEG_DATA_RDWR&lt;br /&gt;
 &lt;br /&gt;
#define GDT_CODE_PL3 SEG_DESCTYPE(1) | SEG_PRES(1) | SEG_SAVL(0) | \&lt;br /&gt;
                     SEG_LONG(0)     | SEG_SIZE(1) | SEG_GRAN(1) | \&lt;br /&gt;
                     SEG_PRIV(3)     | SEG_CODE_EXRD&lt;br /&gt;
 &lt;br /&gt;
#define GDT_DATA_PL3 SEG_DESCTYPE(1) | SEG_PRES(1) | SEG_SAVL(0) | \&lt;br /&gt;
                     SEG_LONG(0)     | SEG_SIZE(1) | SEG_GRAN(1) | \&lt;br /&gt;
                     SEG_PRIV(3)     | SEG_DATA_RDWR&lt;br /&gt;
 &lt;br /&gt;
void&lt;br /&gt;
create_descriptor(uint32_t base, uint32_t limit, uint16_t flag)&lt;br /&gt;
{&lt;br /&gt;
    uint64_t descriptor;&lt;br /&gt;
 &lt;br /&gt;
    // Create the high 32 bit segment&lt;br /&gt;
    descriptor  =  limit       &amp;amp; 0x000F0000;         // set limit bits 19:16&lt;br /&gt;
    descriptor |= (flag &amp;lt;&amp;lt;  8) &amp;amp; 0x00F0FF00;         // set type, p, dpl, s, g, d/b, l and avl fields&lt;br /&gt;
    descriptor |= (base &amp;gt;&amp;gt; 16) &amp;amp; 0x000000FF;         // set base bits 23:16&lt;br /&gt;
    descriptor |=  base        &amp;amp; 0xFF000000;         // set base bits 31:24&lt;br /&gt;
 &lt;br /&gt;
    // Shift by 32 to allow for low part of segment&lt;br /&gt;
    descriptor &amp;lt;&amp;lt;= 32;&lt;br /&gt;
 &lt;br /&gt;
    // Create the low 32 bit segment&lt;br /&gt;
    descriptor |= base  &amp;lt;&amp;lt; 16;                       // set base bits 15:0&lt;br /&gt;
    descriptor |= limit  &amp;amp; 0x0000FFFF;               // set limit bits 15:0&lt;br /&gt;
 &lt;br /&gt;
    printf(&amp;quot;0x%.16llX\n&amp;quot;, descriptor);&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
int&lt;br /&gt;
main(void)&lt;br /&gt;
{&lt;br /&gt;
    create_descriptor(0, 0, 0);&lt;br /&gt;
    create_descriptor(0, 0x000FFFFF, (GDT_CODE_PL0));&lt;br /&gt;
    create_descriptor(0, 0x000FFFFF, (GDT_DATA_PL0));&lt;br /&gt;
    create_descriptor(0, 0x000FFFFF, (GDT_CODE_PL3));&lt;br /&gt;
    create_descriptor(0, 0x000FFFFF, (GDT_DATA_PL3));&lt;br /&gt;
 &lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== 另见 ==&lt;br /&gt;
&lt;br /&gt;
=== 文章 ===&lt;br /&gt;
* [[Global Descriptor Table]]&lt;br /&gt;
* http://web.archive.org/web/20190424213806/http://www.osdever.net/tutorials/view/the-world-of-protected-mode - 如何在汇编程序中设置GDT&lt;br /&gt;
&lt;br /&gt;
=== Threads ===&lt;br /&gt;
&lt;br /&gt;
=== External Links ===&lt;br /&gt;
&lt;br /&gt;
[[Category:Tutorials]]&lt;br /&gt;
[[Category:X86 CPU]]&lt;/div&gt;</summary>
		<author><name>Zhang3</name></author>
	</entry>
</feed>