Chapter3 BASIC EXECUTION ENVIRONMENT

3.3 内存组织

处理器在其总线上地址的内存地址称为物理内存地址。物理内存按 8 位字节序列组织。每个字节都分配一个唯一的地址,称为物理地址地址。如果处理器不支持英特尔 64 架构,则物理地址空间范围为 236 × 1 (64 Gb)。 英特尔 64 架构引入了物理地址和线性地址空间的变化。

3.3.1 IA-32内存模式

  • 平面内存模型– 内存在程序中显示为单个连续地址空间。此空间称为线性地址空间。代码、数据和堆栈都包含在此地址空间中。线性地址空间是可字节寻址的,地址从 0 到 232 -1 (如果不是在 64 位模式下)。线性地址空间中任何字节的地址称为线性地址。
  •   分段内存模型内存在程序中显示为一组称为段的独立地址空间。代码、数据和堆栈通常包含在单独的段中。要解决段中的字节问题,程序会发出逻辑地址。它由段选择器和偏移量组成(逻辑地址通常称为远指针)。段选择器对要访问的段进行标识,偏移量标识段地址空间中的字节。在 IA-32 处理器上运行的程序可以处理多达 16,383 个不同大小和类型的段,并且每个段可以高达 232字节。
  •   实址模式内存型号这是英特尔 8086 处理器的内存型号。支持它提供与编写在英特尔 8086 处理器上运行的现有程序的兼容性。实址模式使用分段内存的特定实现,其中程序和操作系统/执行的线性地址空间由每个大小高达 64 KB 的段数组组成。实地址模式下线性地址空间的最大大小为 220字节。

3.3.2 分页和虚拟内存

使用平面或分段内存模型,线性地址空间直接或通过分页映射到处理器的物理地址空间。使用直接映射(禁用分页),每个线性地址与物理地址具有一对一的对应关系。线性地址在处理器的地址行上发送,无需转换。

当使用 IA-32 体系结构的分页机制(启用了分页),线性地址空间被划分为映射到虚拟内存的页面。然后根据需要将虚拟内存的页映射到物理内存中。当操作系统或执行程序使用分页时,分页机制对应用程序是透明的。应用程序看到的只是线性地址空间。

此外,IA-32 架构的分页机制包括支持以下的扩展:

       物理地址扩展 (PAE) 用于处理大于 4 GB 的物理地址空间。

       页面大小扩展 (PSE) 用于将线性地址映射到 4-Mbtes 页中的物理地址。

3.3.3 64位内存组织

 

英特尔 64 架构支持大于 64 GB 的物理地址空间;IA-32 处理器的实际物理地址大小是特定于实现的。在 64 位模式下, 64 位线性地址空间的体系结构支持。但是,支持英特尔 64 架构的处理器可能实现不到 64 位。线性地址空间通过 PAE 分页机制映射到处理器物理地址空间。

3.3.4 操作模式与内存模型

 

       保护模式当处于受保护模式时,处理器可以使用本节中描述的任何内存。(仅当处理器处于虚拟 8086 模式时,才使用实寻模式内存模型。)使用的内存模型取决于操作系统或执行系统的设计。实现多任务化时,单个任务可以使用不同的内存模型。

       实地址模式在实地址模式下,处理器仅支持实地址模式内存模型。

       系统管理模式- SMM ,处理器切换到单独的地址空间,称为系统管理 RAM (SMRAM)。用于寻址此地址空间中的字节的内存模型与实地址模式模型类似。有关 SMM 中使用的内存模型的详细信息,请参阅英特尔 ® 64 IA-32 体系结构软件开发人员的 Manual 3C中的第 34 "系统管理模式"

       兼容性模式需要在兼容模式下运行的软件应遵循与在 32 位保护模式下运行的内存模型相同的内存模型。分段的效果与 32 位保护模式语义中的效果相同。

       64 位模式-段寄存器通常被(但不是完全)禁用,从而创建平面 64 位线性地址空间。具体来说,处理器在 64 位模式下将 CSDSES SS 的段基视为零(这使得线性地址等于有效地址)。分段和实地址模式在 64 位模式下不可用。

3.3.6 保护模式下的扩展物理寻址

P6 系列处理器开始,IA-32 架构支持高达 64 GB(236字节)的物理内存寻址。程序或任务无法直接寻址此添加空间中的位置。相反,它解决单个线性地址空间,最多 4 Gb,通过虚拟内存管理机制映射到 64 G 字节物理地址空间。使用此机制,操作系统可以使程序在64 G 字节物理地址空间内旋转 4-GByte 线性地址空间。

使用扩展物理寻址需要处理器在受保护模式下运行,操作系统需要提供虚拟内存管理系统。请参阅英特尔® 64 IA-32 体系结构软件开发人员手册的第 3A" 3 "保护模式内存管理"中的"使用 PAE 分页机制的 36 位物理卡寻址"

3.4 基本寄存器

 

IA-32 体系结构提供了 16 个基本程序执行寄存器,用于一般系统和应用程序编程。这些寄存器可以按照以下方式分组:


       通用寄存器。这八个寄存器可用于存储操作数和指针。

       段寄存器。这些寄存器最多包含六个段选择器。

       EFLAGS(程序状态和控制)寄存器。EFLAGS 注册报告正在执行的程序的状态,并允许对处理器进行有限的(应用程序级别)控制。

       EIP(指令指针)寄存器。EIP 寄存器包含指向要执行的下一个指令的 32 位指针。

 

 

3.4.1 通用寄存器

 

提供 32 位通用寄存器 EAXEBXECXEDXESIEDIEBP 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 段中)

 

 

3.4.1.1 64位模式下通用寄存器

64 位模式下, 16 个通用寄存器,默认操作数大小为 32 位。但是,通用寄存器能够处理 32 位或 64 位操作数。如果指定了 32 位操作数大小:提供 EAXEBXECXEDXEDIESIEBPESPR8D - R15D。如果指定了 64 位操作数大小:提供 RAXRBXRCXRDXRDIRSIRBPRSPR8-R15R8D-R15D/R8-R15 代表 8 个新的通用寄存器。所有这些寄存器都可以在byteworddword 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位模式切换之后,软件必须不依赖这些位来维护值。

3.4.2 段寄存器

段寄存器(CSDSSSESFS GS)包含 16 位段选择器。段选择器是标识内存中段的特殊指针。要访问内存中的特定段,该段的段选择器必须出现在适当的段寄存器中。

 

CSDSSS ES 这四个段寄存器与英特尔 8086 和英特尔 286 处理器中的段寄存器相同,FS GS 寄存器通过英特尔 386 ™处理器系列引入 IA-32 架构。

3.4.2.1 64位模式下段寄存器

64 位模式下:无论关联的段描述符基的值如何,CSDSESSS 都被视为每个段基数为 0。这将为代码、数据和堆栈创建 flat 地址空间。FS GS 是例外。在线性地址计算(在本地数据和某些操作系统数据结构的寻址中),这两个段寄存器都可以用作附加基寄存器。

即使分段通常是禁用的,段寄存器加载可能会导致处理器执行段访问检查。在这些活动期间,启用的处理器仍将对加载的值执行大多数遗留检查(即使这些检查不适用于64位模式)。这类检查是必要的,因为以64位模式加载的段寄存器可能被以兼容模式运行的应用程序使用。

64 位模式下禁用对 CSDSESSSFS GS 的限制检查(段界限吗?)

3.4.3 EFLAGS寄存器

 

32 位 EFLAGS 寄存器包含一组状态标志、一个控制标志和一组系统标志。在处理器初始化后(通过断言 RESET 引脚或 INIT 引脚),EFLAGS寄存器的状态为 00000002H。此寄存器的位 1、3、5、15 和 22 到 31 保留。软件不应使用或依赖于这些位中的任何一个状态。

 

 

 可以使用以下指令将一组标志移动到过程堆栈或EAX寄存器:LAHF、SAHF、PUSHF、PUSHFD、POPF和POPFD。将EFLAGS寄存器的内容传输到过程堆栈或EAX寄存器后,可以使用处理器的位操作指令(BT、BTS、BTR和BTC)检查和修改这些标记。

当挂起一个任务(使用处理器的多任务处理设施)时,处理器自动将EFLAGS寄存器的状态保存在任务状态段(TSS)中,以供挂起任务使用。当将自己绑定到一个新任务时,处理器用新任务的TSS中的数据加载EFLAGS寄存器。
当调用中断或异常处理程序时,处理器自动将EFLAGS寄存器的状态保存在过程堆栈上。当使用任务切换处理中断或异常时,EFLAGS寄存器的状态将保存在TSS中,以供挂起任务使用。

3.4.2.1 状态标志

EFLAGS 寄存器的状态标志(位 0、2、4、6、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 (条件移动) 使用一个或多个状态标志作为条件代码,并测试其分支、设置字节或结束循环条件。

3.4.2.2 DF标志

方向标志(DF,位于 EFLAGS 寄存器的位 10 中)控制字符串指令(MOVS、CMPS、SCAS、LODS 和 STOS)。设置 DF 标志会导致字符串指令自动递减(处理从高地址到低地址的字符串)。清除 DF 标志会导致字符串指令自动递增(处理从低添加器到高地址的字符串)。

STD 和 CLD 指令分别设置并清除 DF 标志。

3.4.2.3 系统标志和IOPL字段

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.

3.5 指令指针

指令指针寄存器包含当前代码段中要执行的下一条指令的偏移量。在执行JMP、Jcc、CALL、RET和IRET指令时,它可以在直线代码中从一个指令边界前进到下一个指令边界,也可以由多个指令向前或向后移动。

软件不能直接访问EIP寄存器;它由控制传输指令(如JMP、Jcc、CALL和RET)、中断和异常隐式地控制。读取EIP寄存器的唯一方法是执行一条调用指令,然后从过程堆栈中读取返回指令指针的值。通过修改过程堆栈上返回指令指针的值并执行返回指令(RET或IRET),可以间接加载EIP寄存器。参见6.2.4.2节,“返回指令指针”。

所有IA-32处理器预取指令。由于指令预取,在指令加载期间从总线读取的指令地址与EIP寄存器中的值不匹配。尽管不同的处理器代使用不同的预取机制,EIP寄存器引导程序流的功能仍然完全兼容所有编写在IA-32处理器上运行的软件。(?????)

3.6 操作数大小和地址大小属性

当处理器在受保护模式下执行时,每个代码段都有一个默认的操作数大小属性和地址大小属性。这些属性在代码段的段描述符中使用 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 标志的设置以及操作数大小和地址大小前缀。

3.6.1 64 位模式下的操作数大小和地址大小

在 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 卷)。

 

3.7 操作方式寻址

IA-32 机器指令作用于零个或多个操作数。某些操作数是显式指定的,而其他操作数是隐式的。源操作数的数据可以位于:

  • 指令本身(立即操作数)
  • 寄存器
  • 内存位置
  • I/O 端口

当指令将数据返回到目标操作数时,可以将其返回到:

  • 寄存器
  • 内存位置
  • I/O 端口

3.7.1 立即操作数

某些指令使用指令本身编码的数据作为源操作数。这些操作数称为"立即操作数"(或只是直接操作数)。例如,以下 ADD 指令将 EAX regis ter 的内容添加到立即值 14:

ADD EAX, 14

所有算术指令(DIV 和 IDIV 指令除外)都允许源操作数成为即时值。指令允许的直接操作数的最大值因指令而异,但绝不能大于无符号双字整数 (232)的最大值。

3.7.2                注册操作数

源和目标操作数可以是以下任一寄存器,具体取决于正在执行的指令:

  • 32 位通用寄存器(EAX、EBX、ECX、EDX、ESI、EDI、ESP或 EBP)
  • 16 位通用寄存器(AX、BX、CX、DX、SI、DI、SP 或 BP)
  • 8 位通用寄存器(AH、BH、CH、DH、AL、BL、CL 或 DL)
  • 段寄存器(CS、DS、SS、ES、FS 和 GS)
  • EFLAGS 寄存器
  • x87 FPU 寄存器(ST0 到 ST7、状态字、控制字、标记字、数据操作数指针和指令指针)
  • MMX 寄存器(MM0 至 MM7)
  • XMM 寄存器(XMM0 至 XMM7)和 MXCSR 寄存器
  • 控制寄存器(CR0、CR2、CR3 和 CR4)和系统表指针寄存器(GDTR、LDTR、IDTR和任务寄存器)
  • 调试寄存器(DR0、DR1、DR2、DR3、DR6 和 DR7)
  • MSR 寄存器

某些指令(如 DIV 和 MUL 指令)使用包含在一对 32 位寄存器中的四字操作数。寄存器对用分隔它们的冒号表示。例如,在寄存器对 EDX:EAX 中,EDX 包含高位,EAX 包含四字操作数的低位。

提供了若干说明(如 PUSHFD 和 POPFD 指令)来加载和存储 EFLAGS 寄存器的内容,或在此寄存器中设置或清除单个标志。其他 ininsjin(如 Jcc指令)使用 EFLAGS 寄存器中的状态标志的状态作为分支或其他决策操作的条件代码。

处理器包含一系列系统寄存器,用于控制内存管理、中断和异常处理、任务管理、处理器管理和调试活动。其中一些系统寄存器可通过一组系统指示进行访问,应用程序、操作系统或执行机构可以访问。当使用系统指令访问系统寄存器时,寄存器通常是指令的隐含操作数。

3.7.2.1 在 64 位模式下寄存器操作数

在 64 位模式下寄存器操作数可以是以下任一操作数:

  • 64 位通用寄存器(RAX、RBX、RCX、RDX、RSI、RDI、RSP、RBP 或 R8-R15)
  • 32 位通用寄存器(EAX、EBX、ECX、EDX、ESI、EDI、ESP、EBP 或 R8D-R15D)
  • 16 位通用寄存器(AX、BX、CX、DX、SI、DI、SP、BP 或 R8W-R15W)
  • 8 位通用注册器:AL、BL、CL、DL、SIL、DIL、SPL、BPL 和 R8L-R15L 均使用 REX 前缀;AL、BL、CL、DL、AH、BH、CH、DH 均可用,无需使用 REX 前缀。
  • 分段寄存器(CS、DS、SS、ES、FS 和 GS)
  • RFLAGS 寄存器
  • x87 FPU 寄存器(ST0 到ST7、状态字、控制字、标记字、数据操作数指针和指令指针)
  • MMX 寄存器(MM0 至 MM7)
  • XMM 寄存器(XMM0 至 XMM15)和 MXCSR 寄存器
  • 控制寄存器(CR0、CR2、CR3、CR4 和 CR8)和系统表指针 regisi(GDTR、LDTR、IDTR 和任务寄存器)
  • 调试寄存器(DR0、DR1、DR2、DR3、DR6 和 DR7)
  • MSR 寄存器
  • RDX:RAX 寄存器对,表示 128 位操作数

3.7.3 内存操作数

内存中的源和目标操作数通过段选择器和偏移量进行引用(参见图 3-9)。段选择器指定包含操作数的段。偏移指定操作数的线性或有效地址。偏移量 can 为 32 位(由表示法 m16:32 表示)或 16 位(由表示法 m16:16 表示)。

3.7.3.1  64 位模式下的内存操作数

在 64 位模式下,内存操作数可以由段选择器和偏移量引用。偏移量可以是 16 位、32 位或 64 位(参见图 3-10)。

3.7.4 指定段选择器

可以隐式或显式指定段选择器。指定段选择器的最常见方法是将其加载到段寄存器中,然后允许处理器根据执行的操作数类型隐式选择寄存器。处理器根据表 3-5 中给出的规则自动选择段。

在内存中存储数据或从内存加载数据时,可以重写 DS 段默认值以允许访问其他段。对于汇编器,段覆盖通常使用冒号":"运算符"来处理。例如,以下 MOV 指令将值从寄存器 EAX 移动到 ES 寄存器指向的段。入段的偏移量包含在EBX 寄存器中:MOV ES:[EBX]、EAX

表 3-5. 默认段选择规则

参考类型

已注册

使用的段

默认选择规则

指示

CS

代码段

所有指令。

堆栈

SS

堆栈段

所有堆栈推送和弹出。

使用 ESP 或 EBP 寄存器作为基本寄存器的任何内存引用。

本地数据

DS

数据段

所有数据引用,但相对于堆栈或字符串目标时除外。

目标字符串

ES

使用 ES 寄存器指向的数据段

字符串指令的目标。

在计算机级别,使用段覆盖前缀指定段覆盖,该前缀是放置在指令开头的字节。无法覆盖以下默认段选择:

  • 指令提取必须从代码的参数进行。
  • 字符串指令中的目标字符串必须存储在 ES 寄存器指向的数据段中。
  • 推送和弹出操作必须始终引用 SS 段。

某些指令要求显式指定段选择器。在 These 情况下,16 位段选择器可以位于内存位置或 16 位寄存器中。例如,以下 MOV 指令将位于寄存器 BX 中的段选择器移动到段寄存器 DS 中:

MOV DS, BX

段选择器也可以显式指定为内存中 48 位远指针的一部分。此处,内存中的第一个双字包含偏移量,下一个单词包含段选择器。

3.7.4.1  64 位模式下的分段

在 IA-32e 模式下,分段的效果取决于处理器是在兼容模式还是 64 位模式下运行。在兼容模式下,分段功能与传统 IA-32 模式下的功能相同,使用上述 16 位或 32 位保护模式 semantics。

在 64 位模式下,分割通常(但不是完全)禁用,从而创建一个平面 64 位线性地址空间。处理器将 CS、DS、ES、SS 的段基视为零,创建一个等于有效地址的线性地址。例外情况是 FS 和 GS 段,其段寄存器(包含段基)在某些线性地址计算中可用作附加基寄存器。

3.7.5 指定偏移

内存地址 ca n 的偏移部分直接指定为静态值(称为位移)或通过由以下一个或多个组件组成的地址计算:

  • 位移= 8 位、16 位或 32 位值。
  • = 通用寄存器中的值。
  • 索引= 通用寄存器中的值。
  • 比例因子= 乘以索引值的值 2、4 或 8。

添加这些组件产生的偏移量称为有效地址。除缩放因子外,每个组件都可以具有正值或正(2s 补码)值。图 3-11 显示了将这些组件组合在选定段中创建有效地址的所有可能方法。

通用寄存器作为基元或索引组件的使用受到以下限制:

  • ESP 寄存器不能用作索引寄存器。
  • 当 ESP 或 EBP 寄存器用作基时,SS 段是默认段。在所有其他情况下,DS 段是默认段。

基、索引和位移组件可以任意组合使用,这些组件中的任何一个都可以为 NULL。仅当也使用索引时,才能使用比例因子。每种可能的组合对于高级语言和汇编语言中progr ammer 常用的数据结构都很有用。

以下寻址模式建议地址组件的常见组合的用途。

  • 位移-仅置换表示对操作数的直接(未计算)偏移。由于位移在指令中编码,因此这种形式的地址有时称为绝对或静态地址。它通常用于访问静态 allacat 标量操作数。·基地·000年仅基数表示对操作数的间接偏移。由于基寄存器中的值可以更改,因此可用于变量和数据结构的动态存储。
  • 基础 = 位移=基本寄存器和散点拉板可用于两个不同的目的:

• 当元素大小不是 2、4 或 8 字节时,作为数组中的索引 — 位移组件将静态偏移编码到数组的开头。基本寄存器保存计算结果,以确定数组中特定元素的偏移量。

• 访问记录的字段:基本寄存器保存记录开头的地址,而位移是该字段的静态偏移。

这种组合的一个重要特殊功能是访问过程激活记录中的参数。过程激活记录是在输入过程时创建的堆栈帧。在这里,EBP 寄存器是基本寄存器的最佳选择,因为它会自动选择堆栈段。这是此常见函数的紧凑编码。

  • (索引=刻度) = 位移·000年当元素大小为 2、4 或 8 字节时,此地址模式提供了一种将索引到静态数组的有效方法。位移定位数组的开头,索引寄存器保存所需数组元素的下标,处理器通过应用缩放因子自动将下标转换为索引。
  • 基 = 索引 = 位移=使用两个寄存器,将一个二维数组(位移包含数组开头的地址)或记录数组的几个实例之一(位移是偏移到记录中的字段)。
  • base = (Index = Scale) = 位移=将所有寻址组件一起使用,当数组的元素大小为 2、4 或 8 字节时,可以有效地索引二维数组。

3.7.5.1  在 64 位模式下指定偏移

64 位模式下内存地址的偏移部分可以直接指定为静态值,或通过由以下一个或多个组件组成的地址计算指定:

  • 位移 = 8 位、16 位或 32 位值。
  • 基 = 64位通用寄存器中的值。
  • 索引 = 64 位通用寄存器中的值。
  • 比例因子 =乘以索引值的值 2、4 或 8。

在大多数情况下,基值和索引值可以在 16 个可用的通用寄存器之一中指定。请参阅英特尔® 64 和 IA-32 体系结构软件开发人员手册第 2 卷第 2A 章中的"说明格式"。

还提供以下地址组件的唯一组合。

  • RIP = 位移=在 64 位模式下,RIP-relative 寻址使用带符号的 32 位位移来通过符号扩展 32 位值并添加到 RIP 中的 64 位值来计算下一指令的有效地址。

3.7.6                          汇编器和编译器寻址模式

在机器代码级别,在指令中对位移、基寄存器、索引寄存器和比例因子的seled组合进行编码。所有汇编器都允许程序员使用这些寻址组件的任何允许组合来解决操作数。高级 language 编译器将根据程序员定义的语言构造选择这些组件的适当组合。

3.7.7              I/O 端口寻址

处理器支持包含多达 65,536 个 8 位 I/O 端口的 I/O 地址空间。在I/O 地址空间中也可以定义 ar e 16 位和 32 位端口。I/O 端口可以使用 DX 寄存器中的即时操作数或值进行寻址。有关 I/O 端口寻址的详细信息,请参阅第 18 章"输入/输出"。

 

 

posted @ 2019-07-10 15:03  YangDanMua  阅读(334)  评论(0编辑  收藏  举报