MOV

移动

stableVMJITAOTinstruction

编码

操作码指令Op/En64 位兼容/传统说明
88 /rMOV r/m8, r8MR有效有效将 r8 移动到 r/m8 。
89 /rMOV r/m16, r16MR有效有效将 r16 移动到 r/m16 。
89 /rMOV r/m3, r3MR有效有效将 r3 移动到 r/m32 。
REX.W + 89 /rMOV r/m64, r64MR有效不可编码将 r64 移动到 r/m64 。
8A /rMOV r8, r/m8RM有效有效将 r/m8 移动到 r8 。
8B /rMOV r16, r/m16RM有效有效将 r/m16 移动到 r16 。
8B /rMOV r3, r/m3RM有效有效将 r/m3 移动到 r32 。
REX.W + 8B /rMOV r64, r/m64RM有效不可编码将 r/m64 移动到 r64 。
8C /rMOV r/m16, Sreg2MR有效有效将分区寄存器移动到 r/m16 。
8C /rMOV r16/r32/m16, Sreg2MR有效有效将零扩展的16位分区寄存器移动到 r16/r32/m16.
REX.W + 8C /rMOV r64/m16, Sreg2MR有效有效将 0 扩展的 16 位分区寄存器移动到 r64/m16 。
8E /rMOV Sreg, r/m16RM有效有效将 r/m16 移动到分区寄存器 。
REX.W + 8E /rMOV Sreg, r/m64RM有效有效将 r/m64 的下十六位移动到分区寄存器中.
A0MOV AL, moffs8FD有效有效将字节( 如: offset) 移动到 AL 。
REX.W + A0MOV AL, moffs8FD有效不可编码将字节( offset) 移动到 AL 。
A1MOV AX, moffs16FD有效有效将单词 at( 如: offset) 移动到 AX 。
A1MOV EAX, moffs32FD有效有效将双字移动到 EAX 。
REX.W + A1MOV RAX, moffs64FD有效不可编码将四字移动到 RAX 。
A2MOV moffs8, ALTD有效有效将 AL 移动到( 如: offset) 。
REX.W + A2MOV moffs8, ALTD有效不可编码将 AL 移动到 (offset) 。
A3MOV moffs16, AXTD有效有效将 AX 移动到( 如: offset) 。
A3MOV moffs32, EAXTD有效有效将 EAX 移动到( 如: offset) 。
REX.W + A3MOV moffs64, RAXTD有效不可编码将 RAX 移动到 (offset) 。
B0+ rb ibMOV r8, imm8OI有效有效将 imm8 移动到 r8 。
B8+ rw iwMOV r16, imm16OI有效有效将 imm16 移动到 r16 。
B8+ rd idMOV r3, imm3OI有效有效将 imm3 移动到 r32 。
REX.W + B8+ rd ioMOV r64, imm64OI有效不可编码将 imm64 移动到 r64 。
C6 /0 ibMOV r/m8, imm8MI有效有效将 imm8 移动到 r/m8 。
C7 /0 iwMOV r/m16, imm16MI有效有效将 imm16 移动到 r/m16 。
C7 /0 idMOV r/m3, imm3MI有效有效将 imm3 移动到 r/m32 。
REX.W + C7 /0 idMOV r/m64, imm3MI有效不可编码将 imm3 标志扩展至 64 位到 r/m64 .

操作数编码

每个模式对应上表 Op/En 列的一个取值,说明各操作数按书写顺序分别编码在指令的哪个字段,以及指令对它是读、是写还是两者兼有。

MR

  1. modrm.rm escrituraModRM 字节的 r/m 字段(第 2-0 位);当 mod 字段要求时,还包括 SIB 字节和位移
  2. modrm.reg lecturaModRM 字节的 reg 字段(第 5-3 位)

RM

  1. modrm.reg escrituraModRM 字节的 reg 字段(第 5-3 位)
  2. modrm.rm lecturaModRM 字节的 r/m 字段(第 2-0 位);当 mod 字段要求时,还包括 SIB 字节和位移

FD

  1. AL/AX/EAX/RAX
  2. moffs操作码后的绝对地址

TD

  1. moffs escritura操作码后的绝对地址
  2. AL/AX/EAX/RAX

OI

  1. opcode.reg escritura操作码字节自身的低三位
  2. imm8/16/32/64指令后的立即数,宽度与操作数相同

MI

  1. modrm.rm escrituraModRM 字节的 r/m 字段(第 2-0 位);当 mod 字段要求时,还包括 SIB 字节和位移
  2. imm8/16/32/64指令后的立即数,宽度与操作数相同

实测开销

正在从 arch-data 加载实测数据...

说明

复制第二个操作数(源操作数)到第一个操作数(目标操作数). 源操作数可以是即时值,通用寄存器,区段注册,或内存位置;目的地注册可以是通用寄存器,区段注册,或内存位置. 操作数两个字必须大小相同,可以是字节,单词,双词,也可以是四词.

MOV 指令不能用于装入 CS 寄存器 。 试图这样做会导致操作码的无效例外(#UD). 要装入 CS 寄存器,请使用 JMP, CALL,或 RET 指令.

如果目标操作数是一个分段寄存器(DS,ES,FS,GS,或SS),则源操作数必须是有效的段选择子. 在 保护模式 中,将一个 段选择子 移动到一个片段寄存器中,会自动将与该 段选择子 相关的片段描述符信息加载到片段寄存器的隐藏部分(阴影)中. 在加载此信息时,段选择子和段描述符信息被验证(见下文"操作"算法). 片段描述器数据来自指定的片段选择器的GDT或LDT条目.

一个NULL 段选择子(值000-0003)可以装入DS,ES,FS和GS注册,而不会造成保护例外. 然而,任何后续试图引用其对应的片段寄存器被装入NULL值的片段,都会导致一般保护例外(#GP),并且没有发生内存引用.

用 MOV 指令装入 SS 注册 抑制或抑制一些调试例外,并抑制下列指令边界上的中断. (抑制在发送例外或执行下一个指令后结束. ) 这种行为允许将一个栈指针与下一个指令(MOV ESP,堆点值)一起加载到ESP的寄存器中,然后可以发送一个事件. 见7.8.3节,"交换堆栈时的异常和中断",载于Intel(R)64和IA-32架构软件开发者手册,第3A卷. Intel建议软件使用LSS指令将SS寄存器和ESP加载在一起.

当执行MOV Reg,Sreg时,处理器将Sreg的内容复制到通用寄存器最不重要的16位. 目的地寄存器的上位是大多数IA-32处理器(Pentium Pro处理器及后来的处理器)和所有Intel 64处理器的零,但对于Intel Quark X1000处理器,Pentium和早期处理器的比特31:16是未定义的除外.

在64位模式下,指令的默认操作大小为32位. 使用REX.R前缀可以访问额外的登记册(R8-R15). 使用REX.W前缀将操作提升到64位. 参见本节开头的汇总图,用于编码数据和限制.

行动

DEST := SRC;

Loading a segment register while in protected mode results in special checks and actions, as described in the following listing. These
checks are performed on the segment selector and the segment descriptor to which it points.

IF SS is loaded
    THEN
          IF segment selector is NULL
                THEN #GP(0); FI;
          IF segment selector index is outside descriptor table limits

        OR segment selector's RPL  CPL


          OR segment is not a writable data segment

        OR DPL  CPL

                THEN #GP(selector); FI;
          IF segment not marked present

                THEN #SS(selector);
                ELSE

                      SS := segment selector;
                      SS := segment descriptor; FI;
FI;

IF DS, ES, FS, or GS is loaded with non-NULL selector
THEN

    IF segment selector index is outside descriptor table limits
    OR segment is not a data or readable code segment
    OR ((segment is a data or nonconforming code segment) AND ((RPL > DPL) or (CPL > DPL)))

          THEN #GP(selector); FI;
    IF segment not marked present

          THEN #NP(selector);
          ELSE

                SegmentRegister := segment selector;
                SegmentRegister := segment descriptor; FI;
FI;

IF DS, ES, FS, or GS is loaded with NULL selector
    THEN
          SegmentRegister := segment selector;
          SegmentRegister := segment descriptor;

FI;

受影响的旗帜

None.

异常

保护模式
#GP(0)如果尝试用 NULL 段选择子 加载SS 注册。如果 目标操作数 处于不可写入的区段中。如果 内存操作数 的有效地址在 CS 、 DS、 ES、 FS 或 GS 区段限制之外。如果 DS、 ES、 FS 或 GS 注册中包含 NULL 段选择子 。
#GP(selector)如果 段选择子 指数在描述表限制之外。 如果正在装入SS 寄存器, 而 段选择子 的 RPL 和 片段描述器的 DPL 则不等于 CPL 。 如果正在装入SS 寄存器, 而片段指向的是一个不可写入的数据段。 如果正在装入DS、ES、FS 或 GS 寄存器, 片段指的不是数据或可读代码段。 如果正在装入DS、ES、FS 或 GS 寄存器, 而片段指的是一个数据或非格式代码段, RPL 或 CPL 大于 DPL 。
#SS(0)如果 内存操作数 的有效地址在 SS 段限制之外。
#SS(selector)如果正在装入党卫军登记册,而指向的路段没有标记。
#NP如果正在装入DS,ES,FS或GS寄存器,而指向的片段没有标记. #PF(fault-code) 如果发生页面错误.
#AC(0)如果启用了对齐检查,并且在当前特权级别为3时会给出不对齐的内存引用.
#UD如果尝试加载 CS 寄存器。 如果使用 LOCK 前缀 。
实地址模式
#GP如果内存操作数的有效地址在CS,DS,ES,FS或GS段限制之外.
#SS如果 内存操作数 的有效地址在 SS 段限制之外。
#UD如果尝试加载 CS 寄存器。 如果使用 LOCK 前缀 。
虚拟 8086 模式
#GP(0)如果内存操作数的有效地址在CS,DS,ES,FS或GS段限制之外.
#SS(0)如果 内存操作数 有效地址在 SS 段限制之外. #PF(fault-code) 如果 页面错误 发生.
#AC(0)如果启用对齐检查, 并使用不对齐的内存引用 。
#UD如果尝试加载 CS 寄存器。 如果使用 LOCK 前缀 。
兼容模式
与保护模式中的例外相同.
64 位模式
#GP(0)如果内存地址是非冠词式的。如果试图加载 SS 注册符NULL 段选择子何时CPL=3. 如果试图将党卫军登记册装入NULL 段选择子何时CPL <联合国CPL RPL.
#GP(selector)如果 段选择子 指数在描述表限制之外。 如果描述表的内存访问是非描述表的。 如果正在装入 SS 寄存器, 而 段选择子 的 RPL 和 段描述符的 DPL 则不等于 CPL 。 如果正在装入 SS 寄存器, 而该片段指向的是一个不可写入的数据段。 如果正在装入 DS, ES, FS, 或 GS 寄存器, 或该片段指向的不是数据或可读代码段。 如果正在装入 DS, ES, FS, 或 GS 寄存器的寄存器是数据或不匹配的代码段, 但 RPL 和 CPL 都大于 DPL 。
#SS(0)如果堆栈地址是非冠状的.
#SS(selector)如果正在装入 SS 寄存器, 而指向的片段没有标记 。 #PF(fault-code) 如果发生 页面错误 。
#AC(0)如果启用了对齐检查,并且在当前特权级别为3时会给出不对齐的内存引用.
#UD如果尝试加载 CS 寄存器。 如果使用 LOCK 前缀 。

来源