我正在尝试模拟jmp (opcode ff /4)
的操作。
当提到英特尔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&lt; - [r / m32]”这令我感到沮丧,例如:
%eax=0x100063
(%eax)=0x00fcff10(a wrong address)
我需要直接取%eax
的值而不是访问地址0x100063来获取0x00fcff10。
它不与手册冲突吗?
如果r / m指地址,我该怎么办?
eip=M[r/m]
或eip=M[M[r/m]]
?
答案 0 :(得分:2)
写下来很混乱......
它实际上做的是将r/m
操作数的值写入eip
。直接是寄存器或内存操作数的值取决于它是哪种r/m
操作数,由编码它的mod R/M byte确定(特别是mod
} field。。
因此,FF E0
例如jmp eax
(不是来自内存)。 FF 20
将是jmp [eax]
。
答案 1 :(得分:1)
这来自英特尔IA32架构软件开发人员手册第2卷&#34;
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