栈的增长方向以及某一瞬时可能的数据结构表示
OP_NOP 什么也不做
OP_GOTO +AA 向前移动AA个16bit的指令处继续执行
OP_GOTO_16 +AAAA 向前移动AAAA个16bit的指令处继续执行
OP_GOTO_32 +AAAAAAAA 向前移动AAAAAAAA个16bit的指令处继续执行
OP_INT_TO_LONG *((long*)&v[vA]=(long)v[vB]
OP_INT_TO_FLOAT *((float*)&v[vA]=(float)v[vB]
OP_INT_TO_DOUBLE *((double*)&v[vA]=(double)v[vB]
vA,vB
OP_LONG_TO_INT v[vA]=(int)*((long*)&v[vB])
OP_LONG_TO_FLOAT *((float*)&v[vA])=(float)*((long*)&v[vB])
OP_LONG_TO_DOUBLE *((double*)&v[vA])=(double)*((long*)&v[vB])
vA,vB
OP_FLOAT_TO_DOUBLE *((double*)&v[vA])=(double)*((float*)&v[vB])
OP_DOUBLE_TO_FLOAT *((float*)&v[vA])=(float)*((double*)&v[vB])
vA,vB
OP_INT_TO_LONG *((long*)&v[vA])=(long)v[vB]
OP_INT_TO_FLOAT *((float*)&v[vA])=(float)v[vB]
OP_INT_TO_DOUBLE *((double*)&v[vA])=(double)v[vB]
vA,vB
OP_LONG_TO_INT v[vA]=(int) *((long*)&v[vB])
OP_LONG_TO_FLOAT *((float*)&v[vA])=(float)*((long*)&v[vB])
OP_LONG_TO_DOUBLE *((double*)&v[vA])=(double)*((long*)&v[vB])
vA,vB
OP_FLOAT_TO_DOUBLE *((double*)&v[vA])=(double)*((float*)&v[vB])
OP_DOUBLE_TO_FLOAT *((float*)&v[vA])=(float)*((double*)&v[vB])
vA,vB
OP_FLOAT_TO_INT
OP_FLOAT_TO_LONG
OP_DOUBLE_TO_INT
OP_DOUBLE_TO_LONG
vA,vB
先比较一下有没有越界,如果有的话,如下判断:
>+inf 则令它等于相应的+inf;<-inf则令它等于相应的-inf;如果为NaN则令它等于0。
OP_INT_TO_BYTE *((byte*)&v[vA])=(byte)v[vB]
OP_INT_TO_CHAR *((char*)&v[vA])=(char)v[vB]
OP_INT_TO_SHORT *((short*)&v[vA])=(short)v[vB]
vA,vB
OP_MOVE_FROM16
OP_MOVE_OBJECT_FROM16
vAA,vBBBB
v[vAA]=v[vBBBB]
OP_MOVE_16
OP_MOVE_OBJECT_16
vAAAA,vBBBB
v[vAAAA]=v[vBBBB]
OP_MOVE_WIDE
vA,vB
*((long*)&v[vA])=*((long*)&v[vB])
OP_MOVE_WIDE_FROM16
vAA,vBBBB
*((long*)&v[vAA])=*((long*)&v[vBBBB])
OP_MOVE_WIDE_16
vAAAA,vBBBB
*((long*)&v[vAAAA]=*((long*)&v[vBBBB])
typedef union jvalue {
jboolean z;
jbyte b;
jchar c;
jshort s;
jint i;
jlong j;
jfloat f;
jdouble d;
jobject l;
} jvalue;
OP_MOVE_RESULT
OP_MOVE_RESULT_OBJECT
vAA
v[vAA]=retval.i
OP_MOVE_RESULT_WIDE
vAA
v[vAA]=retval.j
OP_MOVE_EXCEPTION
vAA
v[vAA]=(u4)self->exception;
dvmClearException;
OP_MOVE
OP_MOVE_OBJECT
vA,vB
v[vA]=v[vB]
OP_CMPL_FLOAT
OP_CMPG_FLOAT
OP_CMPL_DOUBLE
OP_CMPG_DOUBLE
OP_CMP_LONG
vAA,vBB,vCC
0,*((type*)&v[vBB])==*((type*)&v[vCC]); -1,*((type*)&v[vBB])<*((type*)&v[vCC]); 1,*((type*)&v[vBB])>*((type*)&v[vCC]); 其它情况(比如有一个值为NaN)则-1(L)、1(G)或0(没有)。 |
v[vAA]= |
OP_IF_EQ ==
OP_IF_NE !=
OP_IF_LT <
OP_IF_GE >=
OP_IF_GT >
OP_IF_LE <=
vA,vB,CCCC
if(v[vA] 比较 v[vB]) then goto CCCC
OP_IF_EQZ ==
OP_IF_NEZ !=
OP_IF_LTZ <
OP_IF_GEZ >=
OP_IF_GTZ >
OP_IF_LEZ <=
vAA,BBBB
if(v[vAA] 比较 0) then goto BBBB
OP_NEG_INT v[vA]=-v[vB]
OP_NOT_INT v[vA]=v[vB]^0xffffffff
OP_NEG_LONG *((long*)v[vA])=-*((long*)v[vB])
OP_NOT_LONG *((long*)v[vA])= *((long*)v[vB]) ^0xffffffffffffffff
OP_NEG_FLOAT *((float*)v[vA])=-*((float*)v[vB])
OP_NEG_DOUBLE *((float*)v[vA])=-*((float*)v[vB])
OP_ADD_INT v[vAA]=v[vBB]+v[vCC]
OP_SUB_INT v[vAA]=v[vBB]-v[vCC]
OP_MUL_INT v[vAA]=v[vBB]*v[vCC]
OP_DIV_INT v[vAA]=v[vBB]/v[vCC]
OP_REM_INT v[vAA]=v[vBB]%v[vCC]
OP_AND_INT v[vAA]=v[vBB]&v[vCC]
OP_OR_INT v[vAA]=v[vBB]|v[vCC]
OP_XOR_INT v[vAA]=v[vBB]^v[vCC]
vAA,vBB,vCC
OP_SHL_INT v[vAA]=((s4)v[vBB])<<(v[vCC]&0x1f)
OP_SHR_INT v[vAA]=((s4)v[vBB])>>(v[vCC]&0x1f)
OP_USHR_INT v[vAA]=((u4)v[vBB])>>(v[vCC]&0x1f)
vAA,vBB,vCC
OP_ADD_INT_LIT16
OP_MUL_INT_LIT16
OP_DIV_INT_LIT16
OP_REM_INT_LIT16
OP_AND_INT_LIT16
OP_OR_INT_LIT16
OP_XOR_INT_LIT16
vA,vB,#+CCCC
v[vA]=(s4)v[vB] op (s2)CCCC
OP_RSUB_INT
vA,vB,#+CCCC
v[vA]=(s2)CCCC-(s4)v[vB]
OP_ADD_INT_LIT8
OP_MUL_INT_LIT8
OP_DIV_INT_LIT8
OP_REM_INT_LIT8
OP_AND_INT_LIT8
OP_OR_INT_LIT8
OP_XOR_INT_LIT8
vAA,vBB,CC
v[vAA]=(s4)v[vB] op (s1)CC
OP_SHL_INT_LIT8
v[vAA]=(s4)v[vBB]<<(CC&1f)
OP_SHR_INT_LIT8
v[vAA]=(s4)v[vBB] >>(CC&1f)
OP_USHR_INT
v[vAA]=(u4)v[vBB] >>(CC&1f)
OP_RSUB_INT_LIT8
v[vAA]=(s1)CC-(s4)v[vBB]
vAA,vBB,CC
OP_ADD_INT_2ADDR
OP_SUB_INT_2ADDR
OP_MUL_INT_2ADDR
OP_DIV_INT_2ADDR
OP_REM_INT_2ADDR
OP_AND_INT_2ADDR
OP_OR_INT_2ADDR
OP_XOR_INT_2ADDR
vA,vB
v[vA]=(s4)v[vA] op (s4)v[vB]
OP_SHL_INT_2ADDR
v[vA]=(s4)v[vA] << (v[vB]&0x1f)
OP_SHR_INT_2ADDR
v[vA]=(s4)v[vA] << (v[vB]&0x1f)
OP_USHR_INT_2ADDR
v[vA]=(u4)v[vA] >> (v[vB]&0x1f)
vA,vB
OP_ADD_LONG
OP_SUB_LONG
OP_MUL_LONG
OP_DIV_LONG
OP_REM_LONG
OP_AND_LONG
OP_OR_LONG
OP_XOR_LONG
vAA,vBB,vCC
*((long*)&v[vAA])=(s8)*((long*)&v[vBB]) op *((long*)&v[vCC])
OP_SHL_LONG_2ADDR
*((long*)&v[vA]=(s8)*((long*)&v[vA]) << (v[vB]= & 0x3f)
OP_SHR_LONG_2ADDR
*((long*)&v[vA]=(s8)*((long*)&v[vA]) >> (v[vB]= & 0x3f)
OP_USHR_LONG_2ADDR
*((long*)&v[vA]=(u8)*((long*)&v[vA]) >> (v[vB]= & 0x3f)
vA,vB
OP_ADD_FLOAT
OP_SUB_FLOAT
OP_MUL_FLOAT
OP_DIV_FLOAT
OP_REM_FLOAT(fmodf)
vAA,vBB,vCC
与OP_XXX_INT类似,不过操作数类型是float
OP_ADD_DOUBLE
OP_SUB_DOUBLE
OP_MUL_DOUBLE
OP_DIV_DOUBLE
OP_REM_DOUBLE(fmod)
vAA,vBB,vCC
与OP_XXX_INT类似,不过操作数类型是double
OP_ADD_FLOAT_2ADDR
OP_SUB_FLOAT_2ADDR
OP_MUL_FLOAT_2ADDR
OP_DIV_FLOAT_2ADDR
OP_REM_FLOAT_2ADDR(fmodf)
vA,vB
与OP_XXX_INT_2ADDR类似,不过操作数类型是float
OP_ADD_DOUBLE_2ADDR
OP_SUB_DOUBLE_2ADDR
OP_MUL_DOUBLE_2ADDR
OP_DIV_DOUBLE_2ADDR
OP_REM_DOUBLE_2ADDR(fmod)
vA,vB
与OP_XXX_INT_2ADDR类似,不过操作数类型是double
instruction | type | regsize |
OP_AGET | u4 |
|
OP_AGET_OBJECT | u4 |
|
OP_AGET_WIDE | s8 | long |
OP_AGET_BOOLEAN | u1 |
|
OP_AGET_BYTE | s1 |
|
OP_AGET_CHAR | u2 |
|
OP_AGET_SHORT | s2 |
|
vAA,vBB,vCC
……
arrayObj = (ArrayObject *)v[vBB]
……
*((regsize*)&v[vAA])=((type*)(arrayObjàcontents))[v[vCC]]
instruction | type | regsize |
OP_APUT | u4 |
|
OP_APUT_WIDE | s8 | long |
OP_APUT_BOOLEAN | u1 |
|
OP_APUT_BYTE | s1 |
|
OP_APUT_CHAR | u2 |
|
OP_APUT_SHORT | s2 |
|
vAA,vBB,vCC
……
arrayObj=(ArrayObject*)v[vBB]
……
((type*)arrayObjàcontents)[v[vCC]]=*((regsize*)&v[vAA])
OP_APUT_OBJECT
……
arrayObj=(ArrayObject*)v[vBB]
……
dvmCanPutArrayElement
……
((u4*)arrayObjàcontents)[v[vCC]]=v[vAA]
OP_IGET_WIDE
OP_IGET_OBJECT
OP_IGET_BOOLEAN
OP_IGET_BYTE
OP_IGET_CHAR
OP_IGET_SHORT
OP_IGET
vA,vB,field@CCCC
v[vA]=v[vB]所在的dex中第CCCC个field(实例域)的值
调用dvmDexGetResolvedField和dvmResolveInstField
OP_IGET_QUICK
OP_IGET_OBJECT_QUICK
OP_IGET_WIDE_QUICK
vA,vB,field@CCCC
v[vA]=v[vB]这个对象的偏移位置为CCCC的field(实例域)的值
OP_IPUT_WIDE
OP_IPUT_OBJECT
OP_IPUT_BOOLEAN
OP_IPUT_BYTE
OP_IPUT_CHAR
OP_IPUT_SHORT
OP_IPUT
vA,vB,field@CCCC
v[vB]所在的dex中第CCCC个field(实例域)的值= v[vA]
调用dvmDexGetResolvedField和dvmResolveInstField
OP_IPUT_QUICK
OP_IPUT_OBJECT_QUICK
OP_IPUT_WIDE_QUICK
vA,vB,field@CCCC
v[vB]这个对象的偏移位置为CCCC的field(实例域)的值= v[vA]
OP_SGET_WIDE
OP_SGET_OBJECT
OP_SGET_BOOLEAN
OP_SGET_BYTE
OP_SGET_CHAR
OP_SGET_SHORT
OP_SGET
vAA,field@BBBB
v[vAA]=当前方法所属的类第BBBB个field(静态域)的值
调用dvmDexGetResolvedField和dvmResolveStaticField
OP_SPUT_WIDE
OP_SPUT_OBJECT
OP_SPUT_BOOLEAN
OP_SPUT_BYTE
OP_SPUT_CHAR
OP_SPUT_SHORT
OP_SPUT
vA,vB,field@CCCC
当前方法所属的类第BBBB个field(静态域)的值=v[vAA]
调用dvmDexGetResolvedField和dvmResolveStaticField
OP_CONST_4
vA,B v[vA]=(B<<28)>>28 扩展符号
OP_CONST_16
vAA,BBBB v[vAA]=(s2)BBBB
OP_CONST
vA,BBBBBBBB v[vAA]=BBBBBBBB
OP_CONST_HIGH16
vAA,BBBB v[vAA]=BBBB<<16
OP_CONST_WIDE_16
vAA,BBBB *((long*)&v[vA])=BBBB
OP_CONST_WIDE_32
vAA,BBBBBBBB *((long*)&v[vA])=BBBB
OP_CONST_WIDE
vAA,BBBBBBBBBBBBBBBB
*((long*)&v[vA])=BBBBBBBBBBBBBBBB
OP_CONST_WIDE_HIGH16
vAA,BBBB *((long*)&v[vA])=BBBB<<48
OP_CONST_STRING
vAA,string@BBBB
v[vAA]=方法所在dex中第BBBB个StringObject对象
OP_CONST_STRING_JUMBO
vAA,string@BBBBBBBB
v[vAA]=方法所在dex中第BBBBBBBB个StringObject对象
OP_CONST_CLASS
vAA,class@BBBB
v[vAA]=方法所在dex中第BBBB个ClassObject对象
OP_MONITOR_ENTER
vAA 获得v[vAA]中对象的锁
OP_MONITOR_EXIT
vAA 释放v[vAA]中的对象的锁
OP_CHECK_CAST
vAA,class@BBBB
v[vAA]所指的对象所属的类是否是方法所在dex的第BBBB个类的子类
OP_INSTANCE_OF
vA,vB,class@CCCC
v[vA]=v[vB]所指对象是否是方法所在dex中第CCCC个类的实例?1:0
OP_ARRAY_LENTH
vA,vB
v[vA]=v[vB]表示的ArrayObject的length
OP_NEW_INSTANCE
vAA,class@BBBB
v[vAA]=方法所在的dex第BBBB个类型的一个新实例
OP_NEW_ARRAY
vA,vB,class@CCCC
arrayClass=方法所在的dex第CCCC个类
v[vA]=arrayClass类型的长度为vB的数组
OP_FILLED_NEW_ARRAY
vB,{vD,vE,vF,vG,vA},class@CCCC
arrayClass为方法所在dex中第CCCC个类
newArray为arrayClass的长度为v[vB]的新数组,其内容[4]=v[vA],[0]~[3]={v[vD],v[vE],v[vF],v[vG]}
OP_FILL_ARRAY_DATA
vAA,BBBBBBBB
将pc偏移为BBBBBBBB处的数据填入v[vAA]处的对象,这组数据本身含有长度和宽度信息。
OP_THROW
vAA
将vAA处的异常对象设到当前线程中去
OP_PACKED_SWITCH
vAA,BBBBBBBB
跳转到pc+BBBBBBBB处的switch表的v[vAA]的入口处
调用的是dvmInterpHandlePackedSwitch
OP_SPARSE_SWITCH
与OP_PACKED_SWITCH类似,不过调用的是dvmInterpHandleSparseSwitch
OP_EXECUTE_INLINE
vB,{vD,vE,vF,vG},inline@CCCC
调用的dvmPerformInlineOpfStd调用inline方法
OP_INVOKE_VIRTUAL_RANGE
vAA,meth@BBBB,vCCCC
新方法为方法所在的dex中的第BBBB个方法
并将v[vCCCC]~v[vCCCC+AA-1]中的内容依次复制到当前帧的输出区
OP_INVOKE_VIRTUAL
vB,{vD,vE,vF,vG,vA},meth@CCCC
新方法为方法所在的dex中的第CCCC个方法
并将vB[vD,vE,vF,vG,vA]中的内容依次复制到当前帧的输出区
OP_INVOKE_SUPER_RANGE
vAA,meth@BBBB,vCCCC
与OP_INVOKE_VIRTUAL_RANGE类似,不过检验的是超类的方法
OP_INVOKE_SUPER
与OP_INVOKE_VIRTUAL类似,不过检验的是超类的方法
OP_INVOKE_INTERFACE_RANGE
vAA,meth@BBBB,vCCCC
与OP_INVOKE_INTERFACE_RANGE类似
OP_INVOKE_INTERFACE
与OP_INVOKE_VIRTUAL类似
OP_INVOKE_SUPER_RANGE
vAA,meth@BBBB,vCCCC
与OP_INVOKE_VIRTUAL_RANGE类似,不过检验的是超类的方法
OP_INVOKE_SUPER
与OP_INVOKE_VIRTUAL类似,不过检验的是超类的方法
OP_INVOKE_DIRECT_RANGE
vAA,meth@BBBB,vCCCC
与OP_INVOKE_VIRTUAL_RANGE类似,不过检验的是超类的方法
OP_INVOKE_DIRECT
与OP_INVOKE_VIRTUAL类似,不过检验的是超类的方法
OP_INVOKE_STATIC_RANGE
vAA,meth@BBBB,vCCCC
与OP_INVOKE_VIRTUAL_RANGE类似,不过检验的是超类的方法
OP_INVOKE_STATIC
与OP_INVOKE_VIRTUAL类似,不过检验的是超类的方法
OP_INVOKE_VIRTUAL_QUICK_RANGE
OP_INVOKE_VIRTUAL_QUICK
OP_INVOKE_SUPER_QUICK_RANGE
OP_INVOKE_SUPER_QUICK
这几个是调用类中的第若干个方法而非dex中的
OP_RETURN_WIDE
vAA
retval.j=*((long*)&v[vAA])
OP_RETURN_VOID
不做什么事
OP_RETURN
OP_RETURN_OBJECT
vAA
retval.i=*((long*)&v[vAA])