3.1.1.1 指令汇总表中的操作码列(无VEX前缀的指令)
上表中的“操作码”列显示了为每种形式的指令生成的目标代码。在可能的情况下,代码以十六进制字节的形式给出,其顺序与它们在内存中出现的顺序相同。 16进制字节以外的条目定义如下:
• REX.W — 表示使用影响操作数大小或指令语义的 REX 前缀。 REX 前缀和其他可选/强制指令前缀的顺序在第 2 章中讨论。请注意,将旧指令提升为 64 位行为的 REX 前缀未在操作码列中明确列出。
• /digit — 0 到 7 之间的数字表示指令的 ModR/M 字节仅使用 r/m(寄存器或内存)操作数。 reg 字段包含提供指令操作码扩展的数字。
• /r — 表示指令的 ModR/M 字节包含一个寄存器操作数和一个 r/m 操作数。
• cb、cw、cd、cp、co、ct — 1 字节 (cb)、2 字节 (cw)、4 字节 (cd)、6 字节 (cp )、操作码后面的 8 字节 (co) 或 10 字节 (ct) 值。该值用于指定代码偏移量,也可能用于指定代码段寄存器的新值。
• ib、iw、id、io — 1 字节 (ib)、2 字节 (iw)、4 字节 (id) 或 8 字节 (io) 立即操作数操作码、ModR/M 字节或比例索引字节之后的指令。操作码确定操作数是否为有符号值。所有字、双字和四字都以低位字节在前。
• +rb, +rw, +rd, +ro — 表示操作码字节的低 3 位用于编码没有 modR/M 字节的寄存器操作数。该指令将低 3 位的操作码字节对应的十六进制值列为 000b。在非 64 位模式下,从 0 到 7 的寄存器代码被添加到操作码字节的十六进制值。在 64 位模式下,表示 REX.b 的四位字段,opcode[2:0] 字段编码指令的寄存器操作数。 “+ro”仅适用于 64 位模式。代码见表3-1。
• +i — 当操作数之一是 FPU 寄存器堆栈中的 ST(i) 时,浮点指令中使用的数字。数字 i(范围从 0 到 7)与加号左侧给出的十六进制字节相加,形成单个操作码字节。
3.1.1.3 操作码汇总表中的指令列
“指令”列给出了在 ASM386 程序中出现的指令语句的语法。
以下是用于表示指令语句中操作数的符号列表:
• rel8 — 指令结束前 128 字节到指令结束后 127 字节范围内的相对地址。
• rel16, rel32 — 与汇编指令在同一代码段内的相对地址。 rel16 符号适用于操作数大小属性为 16 位的指令; rel32 符号适用于具有 32 位操作数大小属性的指令。
• ptr16:16, ptr16:32 — 远指针,通常指向与指令不同的代码段。符号 16:16 表示指针的值有两个部分。冒号左边的值是一个 16 位选择器或指定给代码段寄存器的值。右侧的值对应于目标段内的偏移量。当指令的操作数大小属性为 16 位时使用 ptr16:16 符号;当操作数大小属性为 32 位时使用 ptr16:32 符号。
• r8 — 字节通用寄存器之一:AL、CL、DL、BL、AH、CH、DH、BH、BPL、SPL、DIL和SIL;或使用 REX.R 和 64 位模式时可用的字节寄存器 (R8L - R15L) 之一。
• r16 — 字通用寄存器之一:AX、CX、DX、BX、SP、BP、SI、DI;或使用 REX.R 和 64 位模式时可用的字寄存器 (R8-R15) 之一。
• r32 — 双字通用寄存器之一:EAX、ECX、EDX、EBX、ESP、EBP、ESI、EDI;或在 64 位模式下使用 REX.R 时可用的双字寄存器 (R8D - R15D) 之一。
• r64 — 四字通用寄存器之一:RAX、RBX、RCX、RDX、RDI、RSI、RBP、RSP、R8–R15。这些在使用 REX.R 和 64 位模式时可用。
• imm8 — 立即字节值。 imm8 符号是介于 –128 和 +127 之间的有符号数。对于 imm8 与字或双字操作数组合的指令,立即值被符号扩展以形成一个字或双字。字的高字节用立即数的最高位填充。
• imm16 — 用于操作数大小属性为 16 位的指令的立即字值。这是一个介于 –32,768 和 +32,767 之间的数字。
• imm32 — 立即双字值,用于操作数大小属性为 32 位的指令。它允许使用介于 +2,147,483,647 和 –2,147,483,648 之间的数字。
• imm64 — 立即四字值,用于操作数大小属性为 64 位的指令。该值允许使用介于 +9,223,372,036,854,775,807 和 –9,223,372,036,854,775,808 之间的数字。
• r/m8 — 字节操作数,可以是字节通用寄存器(AL、CL、DL、BL、AH、CH、DH、BH、BPL、SPL)的内容, DIL 和 SIL) 或内存中的一个字节。字节寄存器 R8L - R15L 在 64 位模式下使用 REX.R 可用。
• r/m16 — 用于操作数大小属性为 16 位的指令的字通用寄存器或内存操作数。通用寄存器一词有:AX、CX、DX、BX、SP、BP、SI、DI。内存的内容在有效地址计算提供的地址处找到。字寄存器 R8W - R15W 在 64 位模式下使用 REX.R 可用。
• r/m32 — 用于操作数大小属性为 32 位的指令的双字通用寄存器或内存操作数。双字通用寄存器有:EAX、ECX、EDX、EBX、ESP、EBP、ESI、EDI。内存的内容在有效地址计算提供的地址处找到。在 64 位模式下使用 REX.R 时,双字寄存器 R8D - R15D 可用。
• r/m64 — 四字通用寄存器或内存操作数,用于在使用 REX.W 时操作数大小属性为 64 位的指令。四字通用寄存器有:RAX、RBX、RCX、RDX、RDI、RSI、RBP、RSP、R8-R15;这些仅在 64 位模式下可用。内存的内容在有效地址计算提供的地址处找到。
• m — 内存中的 16、32 或 64 位操作数。
• m8 — 内存中的字节操作数,通常表示为变量或数组名称,但由 DS:(E)SI 或 ES:(E)DI 寄存器指向。在 64 位模式下,它由 RSI 或 RDI 寄存器指向。
• m16 — 内存中的单词操作数,通常表示为变量或数组名称,但由 DS:(E)SI 或 ES:(E)DI 寄存器指向。此命名法仅用于字符串指令。
• m32 — 内存中的双字操作数,通常表示为变量或数组名称,但由 DS:(E)SI 或 ES:(E)DI 寄存器指向。此命名法仅用于字符串指令。
• m64 — 内存中的内存四字操作数。
• m128 — 内存中的内存双四字操作数。
• m16:16、m16:32 和 m16:64 — 包含由两个数字组成的远指针的内存操作数。冒号左边的数字对应于指针的段选择器。右边的数字对应于它的偏移量。
• m16&32、m16&16、m32&32、m16&64 — 由数据项对组成的内存操作数,其大小在 & 符号的左侧和右侧指示。允许所有内存寻址模式。 BOUND 指令使用 m16&16 和 m32&32 操作数来提供包含数组索引上限和下限的操作数。 LIDT 和 LGDT 使用 m16&32 操作数来提供用于加载限制字段的字和用于加载相应 GDTR 和 IDTR 寄存器的基字段的双字。 LIDT 和 LGDT 在 64 位模式下使用 m16&64 操作数来提供一个字来加载限制字段,以及一个四字来加载相应的 GDTR 和 IDTR 寄存器的基字段。
• moffs8、moffs16、moffs32、moffs64 — MOV 指令的某些变体使用的字节、字或双字类型的简单内存变量(内存偏移)。实际地址由相对于段基的简单偏移量给出。指令中没有使用 ModR/M 字节。 moffs 显示的数字表示它的大小,由指令的 address-size 属性决定。
• Sreg — 段寄存器。段寄存器位分配为 ES = 0、CS = 1、SS = 2、DS = 3、FS = 4 和 GS = 5。
• m32fp、m64fp、m80fp — 内存中的单精度、双精度和双扩展精度(分别)浮点操作数。这些符号指定用作 x87 FPU 浮点指令的操作数的浮点值。
• m16int、m32int、m64int — 内存中的字、双字和四字整数(分别)操作数。这些符号指定用作 x87 FPU 整数指令的操作数的整数。
• ST 或 ST(0) — FPU 寄存器堆栈的顶部元素。
• ST(i) — FPU 寄存器堆栈顶部的第 i 个元素(i ← 0 到 7)。
• mm — MMX 寄存器。 64 位 MMX 寄存器为:MM0 到 MM7。
• mm/m32 — MMX 寄存器或 32 位内存操作数的低 32 位。 64 位 MMX 寄存器是:MM0 到 MM7。内存的内容在有效地址计算提供的地址处找到。
• mm/m64 — MMX 寄存器或 64 位内存操作数。 64 位 MMX 寄存器是:MM0 到 MM7。内存的内容在有效地址计算提供的地址处找到。
• xmm — XMM 寄存器。 128 位 XMM 寄存器为:XMM0 到 XMM7; XMM8 到 XMM15 在 64 位模式下使用 REX.R 可用。
• xmm/m32— XMM 寄存器或 32 位内存操作数。 128 位 XMM 寄存器为 XMM0 到 XMM7; XMM8 到 XMM15 在 64 位模式下使用 REX.R 可用。内存的内容在有效地址计算提供的地址处找到。
• xmm/m64 — XMM 寄存器或 64 位内存操作数。 128 位 SIMD 浮点寄存器为 XMM0 到 XMM7; XMM8 到 XMM15 在 64 位模式下使用 REX.R 可用。内存的内容在有效地址计算提供的地址处找到。
• xmm/m128 — XMM 寄存器或 128 位内存操作数。 128 位 XMM 寄存器为 XMM0 到 XMM7; XMM8 到 XMM15 在 64 位模式下使用 REX.R 可用。内存的内容在有效地址计算提供的地址处找到。
• — 表示隐含使用 XMM0 寄存器。当有歧义时,xmm1 使用 XMM 寄存器指示第一个源操作数,而 xmm2 使用 XMM 寄存器指示第二个源操作数。一些指令使用 XMM0 寄存器作为第三个源操作数,用 . 表示。第三个 XMM 寄存器操作数的使用隐含在指令编码中,不影响 ModR/M 编码。
• ymm — YMM 寄存器。 256 位 YMM 寄存器为:YMM0 到 YMM7; YMM8 到 YMM15 在 64 位模式下可用。
• m256 — 内存中的 32 字节操作数。此命名法仅用于 AVX 指令。
• ymm/m256 — YMM 寄存器或 256 位内存操作数。
• — 表示使用 YMM0 寄存器作为隐式参数。
• bnd — 128 位边界寄存器。 BND0 到 BND3。
• mib — 使用SIB 寻址形式的内存操作数,其中索引寄存器不用于地址计算,Scale 被忽略。有效地址计算只使用基址和位移。
• m512 — 内存中的 64 字节操作数。
• zmm/m512 — ZMM 寄存器或 512 位内存操作数。
• {k1}{z} — 用作指令写掩码的掩码寄存器。 64 位 k 寄存器是:k1 到 k7。写掩码规范仅通过 EVEX 前缀提供。掩蔽可以作为合并掩蔽来完成,其中旧值被保留用于被掩蔽的元素或作为归零掩蔽。掩码类型由 EVEX.z 位决定。
• {k1} — 没有 {z}:屏蔽寄存器用作指令写屏蔽,用于不允许归零屏蔽但支持合并屏蔽的指令。这对应于要求 aaa 字段的值不为 0 的指令(例如,gather)和只允许合并屏蔽的存储类型指令。
• k1 — 用作常规操作数(目标或源)的掩码寄存器。 64 位的 k 寄存器是:k0 到 k7。
• mV — 向量内存操作数;操作数大小取决于指令。
• vm32{x,y, z} — 使用 VSIB 内存寻址指定的内存操作数向量数组。内存地址数组使用公共基址寄存器、恒定比例因子和向量索引寄存器指定,其中 XMM 寄存器 (vm32x)、YMM 寄存器 (vm32y) 或 ZMM 寄存器中具有 32 位索引值的各个元素(vm32z)。
• vm64{x,y, z} — 使用 VSIB 内存寻址指定的内存操作数向量数组。内存地址数组使用公共基址寄存器、恒定比例因子和向量索引寄存器指定,其中 XMM 寄存器 (vm64x)、YMM 寄存器 (vm64y) 或 ZMM 寄存器中具有 64 位索引值的各个元素(vm64z)。
• zmm/m512/m32bcst — 操作数可以是 ZMM 寄存器、512 位内存位置或从 32 位内存位置加载的 512 位向量。
• zmm/m512/m64bcst — 操作数可以是 ZMM 寄存器、512 位内存位置或从 64 位内存位置加载的 512 位向量。
• — 表示使用 ZMM0 寄存器作为隐式参数。
• {er} — 表示支持嵌入式舍入控制,仅适用于寄存器-寄存器形式的指令。这也意味着支持 SAE(抑制所有异常)。
• {sae} — 表示支持 SAE(抑制所有异常)。这用于支持 SAE 但不支持嵌入式舍入控制的指令。
• SRC1 — 表示以 VEX/EVEX 前缀编码并具有两个或多个源操作数的指令的指令语法中的第一个源操作数。
• SRC2 — 表示以 VEX/EVEX 前缀编码并具有两个或多个源操作数的指令的指令语法中的第二个源操作数。
• SRC3 — 表示以 VEX/EVEX 前缀编码并具有三个源操作数的指令的指令语法中的第三个源操作数。
• SRC —单源指令中的源。
• DST — 指令中的目的地。该字段由 reg_field 编码。