【问题标题】:Opcode ff /4 which value is give to eip操作码 ff /4 赋予 eip 的值
【发布时间】:2014-11-09 04:15:34
【问题描述】:

我正在尝试模拟jmp (opcode ff /4) 的操作。 当参考 Intel 80386 手册时,我发现:

 IF instruction = near indirect JMP
 (* i.e. operand is r/m16 or r/m32 *)
 THEN
    IF OperandSize = 16
 THEN
     EIP <- [r/m16] AND 0000FFFFH;
 ELSE (* OperandSize = 32 *)
    EIP <- [r/m32];
    FI;
 FI;

"EIP

   %eax=0x100063
   (%eax)=0x00fcff10(a wrong address)

我需要直接取%eax的值而不是访问地址0x100063得到0x00fcff10。 和说明书不冲突吗?

如果 r/m 指的是地址,我该怎么办? eip=M[r/m]eip=M[M[r/m]]?

【问题讨论】:

  • 你的处理器手册一定很老了,该更新了。

标签: assembly x86


【解决方案1】:

写得很混乱..

它实际上所做的是将r/m 操作数的值写入eip。直接是寄存器的值还是内存操作数取决于它是哪种r/m 操作数,由对其进行编码的mod R/M byte 确定(特别是在mod 字段上)。

所以,FF E0 例如将是jmp eax(不是来自记忆)。 FF 20 将是 jmp [eax]

【讨论】:

    【解决方案2】:

    来自“英特尔 IA32 架构软件开发人员手册第 2 卷”

    IF near jump
      THEN IF near relative jump
        THEN
          tempEIP ← EIP + DEST; (* EIP is instruction following JMP instruction*)
        ELSE (* near absolute jump *)
          tempEIP ← DEST;           **<----- this is what you expect to happen**
      FI;
      IF tempEIP is beyond code segment limit THEN #GP(0); FI;
      IF OperandSize = 32
        THEN
          EIP ← tempEIP;            **<----- here it is assigned**
        ELSE (* OperandSize=16 *)
          EIP ← tempEIP AND 0000FFFFH;
      FI;
    FI:
    

    /4 后缀表示 Mod/RM 字节的 REG/OPCODE 字段用于扩展操作码长度,11 位而不是 8 位。所以直接跳转到 EAX 的值是由以下值构成的:

    REG/OPCODE = 100b = 4
    MOD = 11b = 3
    R/M = 000b = 0
    ==> ModR/M Byte (in Hexadecimal) = E0h  (taken from Table 2-2. 32-Bit Addressing Forms with the ModR/M Byte)
    

    JMP EAX 的最终结果是 FF E0

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-07
      • 2020-04-16
      • 2022-01-23
      • 2018-10-18
      • 1970-01-01
      • 2014-08-02
      • 2011-07-19
      • 1970-01-01
      相关资源
      最近更新 更多