作者:yu诚_530 | 来源:互联网 | 2023-08-24 14:54
目录1.遗留前缀(LegacyPrefixes)1.1操作数大小和地址大小前缀1.2段重写前缀1.3Lock前缀1.4重复前缀2.REX前缀(RegisterExten
目录
1. 遗留前缀(Legacy Prefixes)
1.1 操作数大小和地址大小前缀
1.2 段重写前缀
1.3 Lock前缀
1.4 重复前缀
2. REX前缀(Register Extension)
3. VEX前缀(Vector Extension)和XOP前缀(Extension Operand)
指令前缀占据1个字节,置于指令的操作确前,修改操作数或据作数集。指令前缀分3种类型:
(1) 遗留前缀(Legacy Prefixes)
(2) 寄存器扩展前缀或REX前缀(REX Prefixes)
(3) 扩展前缀(Extended Prefixes)
遗留前缀分为五组,在其中,每一个前缀都有一个唯一值。REX前缀使能在64位模式下AMD64寄存器扩展的用法,它单独被分为一组,在其中,前缀的值表示要启用的寄存器扩展功能的组合。扩展前缀提供了一种转义机制,可为具有新功能的指令打开全新的指令编码空间。目前,有两种扩展前缀——VEX和XOP。VEX前缀用于编码AVX指令,XOP用于编码XOP指令。
1. 遗留前缀(Legacy Prefixes)
表1-1显示了遗留前缀。正如表的最左列所示,分为五组。每一个前缀都有一个唯一的十六进制值。遗留前缀可以以任何次序出现在指令中,但是在一个单一指令中只能使用这五组指令前缀每一组中的一个前缀,并未定义使用同一个组中的多个前缀的情况。
关于前缀的用法,有几个限制。例如,地址大小重写前缀(67h)被用于改变单内存操作数在读取或写入访问时的地址大小, 并且仅用于紧随前缀之后的指令。当用于SSE或64位媒体指令时,改用66h前缀来修改操作码。重复前缀仅在某些字符串指令中引起重复。当用于SSE或64位媒体指令的编码时,前缀被重新用于修改操作码。锁定前缀(lock prefix)只能与少量通用指令一起使用。
表1-1概括了指令前缀的功能。
表1-1
1.1 操作数大小和地址大小前缀
操作数大小和地址大小前缀允许在逐条指令的基础上混合数据和指令的大小。通过使用 67h地址大小前缀,可以在任何操作模式下重写指令的默认地址大小。在64位模式下,大部分通用寄存器指令的默认操作数大小是32位,REX前缀指定指定64位操作数大小,66h前缀指定16位操作数大小。REX 前缀优先于66h前缀。
在64位模式下,默认的地址大小是64位。地址大小可以重写为32位。64位模式不再支持16位地址。在兼容模式下,地址大小前缀的产生的作用与遗留X86架构一样。
1.2 段重写前缀
数据段是大部分内存操作数的默认段。有很多指令允许使用这6个段前缀之一重写默认段。当在下列情况下访问数据时,系统会忽略数据段默认段重写前缀:
(1) 当栈被用于数据入栈或出栈时,总是使用SS段。
(2) 当字符串的操作目标是内存时,它总是使用ES段。
双CS段获取指令不能被重写。但是,CS段重写前缀可用于访问作为数据对象的指令以及访问存储在代码段中的数据。
1.3 Lock前缀
Lock前缀引起某些读-修改-写指令以原子的方式执行。这种操作的机制是独立实现的(例如,这种机制可能涉及锁定包含引用内存操作数副本的数据高速缓存线,和/或总线上的总线信令或数据包消息传递)。该前缀旨在让处理器在多处理器系统中独占使用共享内存操作数。此前缀只能与以下写入内存操作数的指令形式一起使用:ADC, ADD, AND, BTC, BTR, BTS, CMPXCHG, CMPXCHG8B, DEC, INC, NEG, NOT, OR, SBB, SUB, XADD, XCHG, 和XOR。如果在其它指令上使用Lock前缀,将引发无效操作码异常。
1.4 重复前缀
有两种重复前缀的字节编码,F3和F2。字节码F3更为通用,且通常被汇编器视为两条不同的指令。字节码F2 仅用于CMPSx 和SCASx指令:
(1) REP (F3h)——这是更为通用的重复前缀,重复执行与字符串操作相关的指令,重复次数由计数寄存器指定(rCX),直到rCX的值为0或零标识(ZF)为0。此前缀与INS, LODS, MOVS, OUTS, 和STOS指令一起使用。
(2) REPE 或REPZ (F3h)——此版本的 REP 前缀按照计数器寄存器(rCX)中指定的次数重复其关联的字符串指令。当 rCX 中的值达到0或零标志(ZF)被置为0时,重复停止。前缀只能用于CMPSx和SCASx指令。
(3) REPNE 或REPNZ (F2h)——REPNE或REPNZ前缀将其关联的字符串指令重复计数器寄存器(rCX)中指定的次数。当rCX 中的值达到0或零标志(ZF)设置为1时,重复停止。前缀只能与CMPSx和SCASx指令一起使用。
2. REX前缀(Register Extension)
REX前缀仅能用于64位模式。它使能64位寄存器扩展。REX前缀指定了以下牲征:
(1) 使用扩展的通用寄存器。
(2) 使用护展的YMM/XMM寄存器。
(3) 使用64位(4字)操作数大小。
(4) 使用扩展控制和调试寄存器。
REX前缀的值介于40h到4Fh之间,具体取值取决于所期望的特定的扩展寄存器的组合。除了少数例外情况,REX前缀要求访问64位通用寄存器或扩展的通用寄存器XMM寄存器之一。有少数几个指令默认采用64位操作数大小并且在访问扩展通用寄存器时不需要指定REX前缀。
一条指令只能有一个REX前缀,而一个这样的前缀就是表达全部64位模式寄存器扩展功能选择所需的全部内容。如果使用前缀,则必须紧接在指令的第一个操作码字节之前。 REX前缀在其他任何位置都将被忽略。15字节的旧指令大小限制仍然适用于包含REX前缀的指令。
3. VEX前缀(Vector Extension)和XOP前缀(Extension Operand)
VEX和XOP 前缀扩展了REX前缀之外的指令编码和操作数规范能力。它们允许对新指令进行编码以及指定三个、四个或五个操作数。 VEX 前缀是C4h和C5h,XOP前缀是 8Eh。
注:对于更详细的指令前缀细节,请参考intel或amd开发文档的对应章节。
参考资料:
Intel和AMD开发文档