处理器在其总线上地址的内存地址称为物理内存地址。物理内存按 8 位字节序列组织。每一个字节都分配一个惟一的地址,称为物理地址地址。若是处理器不支持英特尔 64 架构,则物理地址空间范围为 236 × 1 (64 Gb)。 英特尔 64 架构引入了物理地址和线性地址空间的变化。程序员
使用平面或分段内存模型,线性地址空间直接或经过分页映射处处理器的物理地址空间。使用直接映射(禁用分页)时,每一个线性地址与物理地址具备一对一的对应关系。线性地址在处理器的地址行上发送,无需转换。编程
当使用 IA-32 体系结构的分页机制(启用了分页)时,线性地址空间被划分为映射到虚拟内存的页面。而后根据须要将虚拟内存的页映射到物理内存中。当操做系统或执行程序使用分页时,分页机制对应用程序是透明的。应用程序看到的只是线性地址空间。数组
此外,IA-32 架构的分页机制包括支持如下的扩展:数据结构
• 物理地址扩展 (PAE) 用于处理大于 4 GB 的物理地址空间。架构
• 页面大小扩展 (PSE) 用于将线性地址映射到 4-Mbtes 页中的物理地址。app
英特尔 64 架构支持大于 64 GB 的物理地址空间;IA-32 处理器的实际物理地址大小是特定于实现的。在 64 位模式下,有 64 位线性地址空间的体系结构支持。可是,支持英特尔 64 架构的处理器可能实现不到 64 位。线性地址空间经过 PAE 分页机制映射处处理器物理地址空间。ide
• 保护模式– 当处于受保护模式时,处理器可使用本节中描述的任何内存。(仅当处理器处于虚拟 8086 模式时,才使用实寻模式内存模型。)使用的内存模型取决于操做系统或执行系统的设计。实现多任务化时,单个任务可使用不一样的内存模型。函数
• 实地址模式– 在实地址模式下,处理器仅支持实地址模式内存模型。测试
• 系统管理模式-在 SMM 中,处理器切换到单独的地址空间,称为系统管理 RAM (SMRAM)。用于寻址此地址空间中的字节的内存模型与实地址模式模型相似。有关 SMM 中使用的内存模型的详细信息,请参阅英特尔 ® 64 和 IA-32 体系结构软件开发人员的 Manual 卷3C中的第 34 章"系统管理模式"。编码
• 兼容性模式– 须要在兼容模式下运行的软件应遵循与在 32 位保护模式下运行的内存模型相同的内存模型。分段的效果与 32 位保护模式语义中的效果相同。
• 64 位模式-段寄存器一般被(但不是彻底)禁用,从而建立平面 64 位线性地址空间。具体来讲,处理器在 64 位模式下将 CS、DS、ES 和 SS 的段基视为零(这使得线性地址等于有效地址)。分段和实地址模式在 64 位模式下不可用。
从 P6 系列处理器开始,IA-32 架构支持高达 64 GB(236字节)的物理内存寻址。程序或任务没法直接寻址此添加空间中的位置。相反,它解决单个线性地址空间,最多 4 Gb,经过虚拟内存管理机制映射到 64 G 字节物理地址空间。使用此机制,操做系统可使程序在64 G 字节物理地址空间内旋转 4-GByte 线性地址空间。
使用扩展物理寻址须要处理器在受保护模式下运行,操做系统须要提供虚拟内存管理系统。请参阅英特尔® 64 和 IA-32 体系结构软件开发人员手册的第 3A卷"第 3 章"保护模式内存管理"中的"使用 PAE 分页机制的 36 位物理卡寻址"。
IA-32 体系结构提供了 16 个基本程序执行寄存器,用于通常系统和应用程序编程。这些寄存器能够按照如下方式分组:
• 通用寄存器。这八个寄存器可用于存储操做数和指针。
• 段寄存器。这些寄存器最多包含六个段选择器。
• EFLAGS(程序状态和控制)寄存器。EFLAGS 注册报告正在执行的程序的状态,并容许对处理器进行有限的(应用程序级别)控制。
• EIP(指令指针)寄存器。EIP 寄存器包含指向要执行的下一个指令的 32 位指针。
提供 32 位通用寄存器 EAX、EBX、ECX、EDX、ESI、EDI、EBP 和 ESP,用于保存如下项目:
• 逻辑运算和算术运算的操做数
• 地址计算的操做数
• 内存指针
尽管全部这些寄存器均可用于通常操做数、结果和指针的操做,但引用 ESP 寄存器时应谨慎使用。ESP 寄存器保存堆栈指针,做为通常规则,不该用于其余目的。
本卷第 5 章"指令集摘要"介绍了通用寄存器的特殊用途。另请参阅:英特尔第 3 章、第 4 章和第 5 章® 64 和 IA-32 体系结构软件开发人员手册、第 2A卷、2B和 2C卷。如下是特殊用途的摘要:
• EAX = 用于操做数和结果数据的累加器
• EBX = 指向 DS 段中的数据的指针
• ECX = 字符串和循环操做的计数器
• EDX = I/O 指针
• ESI = 指向 DS 寄存器指向的段中数据的指针;字符串操做的源指针
• EDI = 指向 ES 寄存器指向的段中的数据(或目标)的指针;字符串操做的目标指针
• ESP = 堆栈指针(在 SS 段中)
• EBP = 指向堆栈上数据的指针(在 SS 段中)
在 64 位模式下,有 16 个通用寄存器,默认操做数大小为 32 位。可是,通用寄存器可以处理 32 位或 64 位操做数。若是指定了 32 位操做数大小:提供 EAX、EBX、ECX、EDX、EDI、ESI、EBP、ESP、R8D - R15D。若是指定了 64 位操做数大小:提供 RAX、RBX、RCX、RDX、RDI、RSI、RBP、RSP、R8-R15。R8D-R15D/R8-R15 表明 8 个新的通用寄存器。全部这些寄存器均可以在byte、word、dword和 qword 级别访问。REX 前缀用于生成 64 位操做数大小或引用寄存器 R8-R15。
仅在 64 位模式(R8-R15 和 XMM8-XMM15)下提供的寄存器在从 64 位模式到兼容性模式的过渡中保留,而后从新转换为 64 位模式。可是,R8-R15 和 XMM8-XMM15 的值在从 64 位模式经过兼容性模式过渡到旧模式或实模式,而后经过兼容性模式返回 64 位模式后未定义。
在64位模式下,访问字节寄存器有一些限制。指令不能同时引用旧的高字节(例如:AH、BH、CH、DH)和一个新的字节寄存器(例如:RAX寄存器的低字节)。可是,指令能够同时引用旧的低字节(例如:AL、BL、CL或DL)和新字节寄存器(例如:R8寄存器的低字节,或RBP)。该体系结构经过使用REX前缀将指令的高字节引用(AH、BH、CH、DH)更改成低字节引用(BPL、SPL、DIL、SIL: RBP、RSP、RDI和RSI的低8位)来实现这一限制。
因为64位通用寄存器的上32位在32位模式中没有定义,因此当从64位模式切换到32位模式(切换到受保护模式或兼容模式)时,任何通用寄存器的上32位都不会被保留。在64位到32位模式切换以后,软件必须不依赖这些位来维护值。
段寄存器(CS、DS、SS、ES、FS 和 GS)包含 16 位段选择器。段选择器是标识内存中段的特殊指针。要访问内存中的特定段,该段的段选择器必须出如今适当的段寄存器中。
CS、DS、SS 和 ES 这四个段寄存器与英特尔 8086 和英特尔 286 处理器中的段寄存器相同,FS 和 GS 寄存器经过英特尔 386 ™处理器系列引入 IA-32 架构。
在 64 位模式下:不管关联的段描述符基的值如何,CS、DS、ES、SS 都被视为每一个段基数为 0。这将为代码、数据和堆栈建立 flat 地址空间。FS 和 GS 是例外。在线性地址计算(在本地数据和某些操做系统数据结构的寻址中),这两个段寄存器均可以用做附加基寄存器。
即便分段一般是禁用的,段寄存器加载可能会致使处理器执行段访问检查。在这些活动期间,启用的处理器仍将对加载的值执行大多数遗留检查(即便这些检查不适用于64位模式)。这类检查是必要的,由于以64位模式加载的段寄存器可能被以兼容模式运行的应用程序使用。
在 64 位模式下禁用对 CS、DS、ES、SS、FS 和 GS 的限制检查(段界限吗?)
3.4.3 EFLAGS寄存器
32 位 EFLAGS 寄存器包含一组状态标志、一个控制标志和一组系统标志。在处理器初始化后(经过断言 RESET 引脚或 INIT 引脚),EFLAGS寄存器的状态为 00000002H。此寄存器的位 一、三、五、15 和 22 到 31 保留。软件不该使用或依赖于这些位中的任何一个状态。
可使用如下指令将一组标志移动到过程堆栈或EAX寄存器:LAHF、SAHF、PUSHF、PUSHFD、POPF和POPFD。将EFLAGS寄存器的内容传输到过程堆栈或EAX寄存器后,可使用处理器的位操做指令(BT、BTS、BTR和BTC)检查和修改这些标记。
当挂起一个任务(使用处理器的多任务处理设施)时,处理器自动将EFLAGS寄存器的状态保存在任务状态段(TSS)中,以供挂起任务使用。当将本身绑定到一个新任务时,处理器用新任务的TSS中的数据加载EFLAGS寄存器。
当调用中断或异常处理程序时,处理器自动将EFLAGS寄存器的状态保存在过程堆栈上。当使用任务切换处理中断或异常时,EFLAGS寄存器的状态将保存在TSS中,以供挂起任务使用。
EFLAGS 寄存器的状态标志(位 0、二、四、六、7 和 11)指示算术指令(如 ADD、SUB、MUL 和 DIV 指令)的结果
CF(位 0) |
进位标志位- 设置若是算术运算生成携带或借用结果的最有符号的icant 位;不然清除。此标志指示无符号整数算术的溢出条件。它还用于多精度算术。 |
PF(位 2) |
奇偶校验标志位- 若是结果中最低显著性字节包含 1 位的偶数,则设置;不然清除。 |
AF(位 4) |
辅助进位标志位- 设置若是算术运算生成携带或借用结果的位 3;不然清除。此 flag 用于二进制编码十进制 (BCD) 算术。 |
ZF(位 6) |
零标志位- 若是结果为零,则设置;不然清除。 |
SF(位 7) |
符号标志位- 设置为等于结果中最重要的位,即带符号整数的符号位。(0 表示正值,1 表示负值。 |
OF(位 11) |
溢出标志位- 若是整数结果太大,则设置正数或负数过小(不包括符号位),以适合目标操做数;不然清除。此标志指示符号整数(两个补码)的溢出条件。 |
在这些状态标志中,只有 CF 标志能够直接修改,使用 STC、CLC 和 CMC 指令。此外,位指令(BT、BTS、BTR 和 BTC)将指定的位复制到 CF 标志中。
状态标志容许单个算术运算为三种不一样的数据类型生成结果:无符号整数、有符号整数和 BCD 整数。若是算术运算的结果被视为无符号整数,CF 标志表示范围外条件(进位或借位);若是 做为符号整数(两个补号)吃,则 OF 标志表示进位或借位;若是被视为 BCD 数字,则 AF 标志表示进位或借位。SF 标志表示带符号的整数的符号。ZF标志指示有符号或无符号整数零。
在整数上执行多精度算术时,CF 标志与带进位 (ADC) 的加法一块儿使用,并减去借用 (SBB) 指令,将进位或借位从一个计算传播到下一个计算。
条件指令 Jcc (跳转到条件代码cc),SETcc (字节设置条件代码cc),LOOPcc, 和CMOVcc (条件移动) 使用一个或多个状态标志做为条件代码,并测试其分支、设置字节或结束循环条件。
方向标志(DF,位于 EFLAGS 寄存器的位 10 中)控制字符串指令(MOVS、CMPS、SCAS、LODS 和 STOS)。设置 DF 标志会致使字符串指令自动递减(处理从高地址到低地址的字符串)。清除 DF 标志会致使字符串指令自动递增(处理从低添加器到高地址的字符串)。
STD 和 CLD 指令分别设置并清除 DF 标志。
EFLAGS 寄存器控制操做系统或执行操做中的系统标志和 IOPL 字段。应用程序不该修改它们.系统标志的功能以下:
TF(位 8) | 陷阱标志 -设置为启用单步模式进行调试;清除以禁用单步模式。 |
IF(位 9) |
中断启用标志- 控制处理器对可屏蔽中断请求的响应。设置为响应可屏蔽中断;清除以抑制可屏蔽的中断 |
IOPL(位 12 and 13) |
I/O 权限级别字段= 指示当前正在运行的程序或任务的 I/O 权限级别。当前正在运行的程序或任务的当前特权级别 (CPL) 必须小于或等于 I/O 特权级别才能访问 I/O地址空间。只有在 CPL 为 0 时,POPF 和 IRET 指令才能修改此字段。 |
NT (位 14) |
嵌套任务标志-控制中断和调用任务的连接。设置当前任务连接到之前执行的 task 时;当当前任务未连接到其余任务时清除。 |
RF(位 16) |
恢复标志-控制处理器对调试异常的响应。 |
VM(位 17) |
虚拟8086模式标- 设置为启用虚拟8086模式;清除以返回保护模式,而不使用虚拟-8086模式语义。 |
AC(位 18) |
对齐检查(或访问控制)标志- 若是在 CR0 寄存器中设置了 AM 位,则仅当此标志为 1 时,将启用用户模式数据访问的对齐检查。 若是在 CR4 寄存器中设置了 SMAP 位,则若是此位为 1,则容许对用户模式页的显式管理模式数据访问。参见英特尔第 4.6 节"访问权限"® 64 和 IA-32 体系结构软件开发人员手册,第 3A 卷。 |
VIF(位 19) |
虚拟中断标志= IF 标志的虚拟映像。与 VIP 标志一块儿使用。(要使用此标志和 VIP 标志经过设置控制寄存器 CR4 中的 VME 标志来启用虚拟模式扩展。 |
VIP (位 20) |
虚拟中断挂起标志= 设置为指示中断处于挂起状态;当没有中断挂起时清除。(软件设置并清除此标志;处理器仅读取它。与 VIF 标志一块儿使用。 |
ID(位 21) |
标识标志-程序可以发出或清除此标志,表示对 CPUID 指令的支持。 |
3.4.3.4 RFLAGS Register in 64-Bit Mode
In 64-bit mode, EFLAGS is extended to 64 bits and called RFLAGS. The upper 32 bits of RFLAGS register is reserved. The lower 32 bits of RFLAGS is the same as EFLAGS.
指令指针寄存器包含当前代码段中要执行的下一条指令的偏移量。在执行JMP、Jcc、CALL、RET和IRET指令时,它能够在直线代码中从一个指令边界前进到下一个指令边界,也能够由多个指令向前或向后移动。
软件不能直接访问EIP寄存器;它由控制传输指令(如JMP、Jcc、CALL和RET)、中断和异常隐式地控制。读取EIP寄存器的惟一方法是执行一条调用指令,而后从过程堆栈中读取返回指令指针的值。经过修改过程堆栈上返回指令指针的值并执行返回指令(RET或IRET),能够间接加载EIP寄存器。参见6.2.4.2节,“返回指令指针”。
全部IA-32处理器预取指令。因为指令预取,在指令加载期间从总线读取的指令地址与EIP寄存器中的值不匹配。尽管不一样的处理器代使用不一样的预取机制,EIP寄存器引导程序流的功能仍然彻底兼容全部编写在IA-32处理器上运行的软件。(?????)
当处理器在受保护模式下执行时,每一个代码段都有一个默认的操做数大小属性和地址大小属性。这些属性在代码段的段描述符中使用 D(默认大小)标志选择(请参阅英特尔® 64 和 IA-32 体系结构软件开发人员手册的第 3A 卷中的第 3 章"受保护模式内存管理").设置 D 标志时,将选择 32 位操做数大小和地址大小属性;若是设置 D 标志,则选择 32 位操做数大小和地址大小属性。当标志清晰时,将选择 16 位大小属性。当处理器在实地址模式、虚拟 8086 模式或 SMM 中执行时,默认操做数大小和地址大小属性始终为 16 位。
操做数大小属性选择操做数的大小。当 16 位操做数大小属性生效时,操做数一般能够是 8 位或 16 位,当 32 位操做数大小属性生效时,操做数一般能够是 8 位或 32 位。
地址大小属性选择用于解决内存的地址大小:16 位或 32 位。当 16 位地址大小属性生效时,段偏移和位移为 16 位。此限制将段的大小限制为 64 KBytes。当 32 位地址大小属性生效时,段偏移和位移为 32 位,容许寻址多达 4 Gb。
经过将操做数大小和/或地址大小前缀添加到指令中,能够覆盖特定指令的默认操做数大小属性和/或地址大小属性。请参阅英特尔® 64 和 IA-32 体系结构软件开发人员手册第 2 卷第 2A 章中的"说明格式"。前缀的效果仅适用于目标指令.
显示有效的操做数大小和地址大小(在受保护模式或兼容性模式下执行时),具体取决于 D 标志的设置以及操做数大小和地址大小前缀。
在 64 位模式下,默认地址大小为 64 位,默认操做数大小为 32 位。可使用前缀覆盖默认值。地址大小和操做数大小前缀容许按指示方式混合 32/64 位数据和 32/64 位地址。表 3-4 显示了 66H 指令前缀和 REX 的有效组合。W 前缀,可用于在 64 位模式下指定操做数大小覆盖。请注意,在 64 位模式下不支持 16 位地址。
REX 前缀由 4-bit 字段组成,这些字段构成 16 个不一样的值。REX 前缀中的 W 位字段称为 REX。W. 若是 REX.W 字段设置正确,前缀指定操做数大小覆盖为 64 位。请注意,软件仍可使用操做数大小 66H 前缀切换为 16 位操做数大小。可是,设置 REX。使用 W 时,W 优先于操做数大小前缀 (66H)。
对于 SSE/SSE2/SSE3/SSSE3 SIMD 指令:操做码扩展必须使用 66H、F2H 和 F3H 前缀。在这种状况下,有效的 REX 之间没有交互。W 前缀和 66H 操做码扩展前缀。
请参阅英特尔第 2 章"指令格式"® 64 和 IA-32 体系结构软件开发人员手册(第 2A 卷)。
IA-32 机器指令做用于零个或多个操做数。某些操做数是显式指定的,而其余操做数是隐式的。源操做数的数据能够位于:
当指令将数据返回到目标操做数时,能够将其返回到:
某些指令使用指令自己编码的数据做为源操做数。这些操做数称为"当即操做数"(或只是直接操做数)。例如,如下 ADD 指令将 EAX regis ter 的内容添加到当即值 14:
ADD EAX, 14
全部算术指令(DIV 和 IDIV 指令除外)都容许源操做数成为即时值。指令容许的直接操做数的最大值因指令而异,但毫不能大于无符号双字整数 (232)的最大值。
源和目标操做数能够是如下任一寄存器,具体取决于正在执行的指令:
某些指令(如 DIV 和 MUL 指令)使用包含在一对 32 位寄存器中的四字操做数。寄存器对用分隔它们的冒号表示。例如,在寄存器对 EDX:EAX 中,EDX 包含高位,EAX 包含四字操做数的低位。
提供了若干说明(如 PUSHFD 和 POPFD 指令)来加载和存储 EFLAGS 寄存器的内容,或在此寄存器中设置或清除单个标志。其余 ininsjin(如 Jcc指令)使用 EFLAGS 寄存器中的状态标志的状态做为分支或其余决策操做的条件代码。
处理器包含一系列系统寄存器,用于控制内存管理、中断和异常处理、任务管理、处理器管理和调试活动。其中一些系统寄存器可经过一组系统指示进行访问,应用程序、操做系统或执行机构能够访问。当使用系统指令访问系统寄存器时,寄存器一般是指令的隐含操做数。
在 64 位模式下寄存器操做数能够是如下任一操做数:
内存中的源和目标操做数经过段选择器和偏移量进行引用(参见图 3-9)。段选择器指定包含操做数的段。偏移指定操做数的线性或有效地址。偏移量 can 为 32 位(由表示法 m16:32 表示)或 16 位(由表示法 m16:16 表示)。
在 64 位模式下,内存操做数能够由段选择器和偏移量引用。偏移量能够是 16 位、32 位或 64 位(参见图 3-10)。
能够隐式或显式指定段选择器。指定段选择器的最多见方法是将其加载到段寄存器中,而后容许处理器根据执行的操做数类型隐式选择寄存器。处理器根据表 3-5 中给出的规则自动选择段。
在内存中存储数据或从内存加载数据时,能够重写 DS 段默认值以容许访问其余段。对于汇编器,段覆盖一般使用冒号":"运算符"来处理。例如,如下 MOV 指令将值从寄存器 EAX 移动到 ES 寄存器指向的段。入段的偏移量包含在EBX 寄存器中:MOV ES:[EBX]、EAX
参考类型 |
已注册 |
使用的段 |
默认选择规则 |
指示 |
CS |
代码段 |
全部指令。 |
堆栈 |
SS |
堆栈段 |
全部堆栈推送和弹出。 使用 ESP 或 EBP 寄存器做为基本寄存器的任何内存引用。 |
本地数据 |
DS |
数据段 |
全部数据引用,但相对于堆栈或字符串目标时除外。 |
目标字符串 |
ES |
使用 ES 寄存器指向的数据段 |
字符串指令的目标。 |
在计算机级别,使用段覆盖前缀指定段覆盖,该前缀是放置在指令开头的字节。没法覆盖如下默认段选择:
某些指令要求显式指定段选择器。在 These 状况下,16 位段选择器能够位于内存位置或 16 位寄存器中。例如,如下 MOV 指令将位于寄存器 BX 中的段选择器移动到段寄存器 DS 中:
MOV DS, BX
段选择器也能够显式指定为内存中 48 位远指针的一部分。此处,内存中的第一个双字包含偏移量,下一个单词包含段选择器。
在 IA-32e 模式下,分段的效果取决于处理器是在兼容模式仍是 64 位模式下运行。在兼容模式下,分段功能与传统 IA-32 模式下的功能相同,使用上述 16 位或 32 位保护模式 semantics。
在 64 位模式下,分割一般(但不是彻底)禁用,从而建立一个平面 64 位线性地址空间。处理器将 CS、DS、ES、SS 的段基视为零,建立一个等于有效地址的线性地址。例外状况是 FS 和 GS 段,其段寄存器(包含段基)在某些线性地址计算中可用做附加基寄存器。
内存地址 ca n 的偏移部分直接指定为静态值(称为位移)或经过由如下一个或多个组件组成的地址计算:
添加这些组件产生的偏移量称为有效地址。除缩放因子外,每一个组件均可以具备正值或正(2s 补码)值。图 3-11 显示了将这些组件组合在选定段中建立有效地址的全部可能方法。
通用寄存器做为基元或索引组件的使用受到如下限制:
基、索引和位移组件能够任意组合使用,这些组件中的任何一个均可觉得 NULL。仅当也使用索引时,才能使用比例因子。每种可能的组合对于高级语言和汇编语言中progr ammer 经常使用的数据结构都颇有用。
如下寻址模式建议地址组件的常见组合的用途。
• 当元素大小不是 二、4 或 8 字节时,做为数组中的索引 — 位移组件将静态偏移编码到数组的开头。基本寄存器保存计算结果,以肯定数组中特定元素的偏移量。
• 访问记录的字段:基本寄存器保存记录开头的地址,而位移是该字段的静态偏移。
这种组合的一个重要特殊功能是访问过程激活记录中的参数。过程激活记录是在输入过程时建立的堆栈帧。在这里,EBP 寄存器是基本寄存器的最佳选择,由于它会自动选择堆栈段。这是此常见函数的紧凑编码。
64 位模式下内存地址的偏移部分能够直接指定为静态值,或经过由如下一个或多个组件组成的地址计算指定:
在大多数状况下,基值和索引值能够在 16 个可用的通用寄存器之一中指定。请参阅英特尔® 64 和 IA-32 体系结构软件开发人员手册第 2 卷第 2A 章中的"说明格式"。
还提供如下地址组件的惟一组合。
在机器代码级别,在指令中对位移、基寄存器、索引寄存器和比例因子的seled组合进行编码。全部汇编器都容许程序员使用这些寻址组件的任何容许组合来解决操做数。高级 language 编译器将根据程序员定义的语言构造选择这些组件的适当组合。
处理器支持包含多达 65,536 个 8 位 I/O 端口的 I/O 地址空间。在I/O 地址空间中也能够定义 ar e 16 位和 32 位端口。I/O 端口可使用 DX 寄存器中的即时操做数或值进行寻址。有关 I/O 端口寻址的详细信息,请参阅第 18 章"输入/输出"。