栈的增长方向以及某一瞬时可能的数据结构表示
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_INTv[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_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 {
jbooleanz;
jbyteb;
jcharc;
jshorts;
jinti;
jlongj;
jfloatf;
jdoubled;
jobjectl;
} 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_INTv[vA]=-v[vB]
OP_NOT_INTv[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_INTv[vAA]=v[vBB]+v[vCC]
OP_SUB_INTv[vAA]=v[vBB]-v[vCC]
OP_MUL_INTv[vAA]=v[vBB]*v[vCC]
OP_DIV_INTv[vAA]=v[vBB]/v[vCC]
OP_REM_INTv[vAA]=v[vBB]%v[vCC]
OP_AND_INTv[vAA]=v[vBB]&v[vCC]
OP_OR_INTv[vAA]=v[vBB]|v[vCC]
OP_XOR_INTv[vAA]=v[vBB]^v[vCC]
vAA,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,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,#+CCCC
v[vA]=(s4)v[vB] op (s2)CCCC
OP_RSUB_INT
vA,#+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,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,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,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,vCC
与OP_XXX_INT类似,不过操作数类型是float
OP_ADD_DOUBLE
OP_SUB_DOUBLE
OP_MUL_DOUBLE
OP_DIV_DOUBLE
OP_REM_DOUBLE(fmod)
vAA,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,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,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,field@CCCC
v[vA]=v[vB]所在的dex中第CCCC个field(实例域)的值
调用dvmDexGetResolvedField和dvmResolveInstField
OP_IGET_QUICK
OP_IGET_OBJECT_QUICK
OP_IGET_WIDE_QUICK
vA,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,field@CCCC
v[vB]所在的dex中第CCCC个field(实例域)的值= v[vA]
调用dvmDexGetResolvedField和dvmResolveInstField
OP_IPUT_QUICK
OP_IPUT_OBJECT_QUICK
OP_IPUT_WIDE_QUICK
vA,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,field@CCCC
当前方法所属的类第BBBB个field(静态域)的值=v[vAA]
调用dvmDexGetResolvedField和dvmResolveStaticField
OP_CONST_4
vA,Bv[vA]=(B<<28)>>28扩展符号
OP_CONST_16
vAA,BBBBv[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,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,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,vG},inline@CCCC
调用的dvmPerformInlineOpfStd调用inline方法
OP_INVOKE_VIRTUAL_RANGE
vAA,meth@BBBB,vCCCC
并将v[vCCCC]~v[vCCCC+AA-1]中的内容依次复制到当前帧的输出区
OP_INVOKE_VIRTUAL
vB,meth@CCCC
OP_INVOKE_SUPER_RANGE
vAA,vCCCC
与OP_INVOKE_VIRTUAL_RANGE类似,不过检验的是超类的方法
OP_INVOKE_SUPER
与OP_INVOKE_VIRTUAL类似,不过检验的是超类的方法
OP_INVOKE_INTERFACE_RANGE
vAA,vCCCC
与OP_INVOKE_INTERFACE_RANGE类似
OP_INVOKE_INTERFACE
与OP_INVOKE_VIRTUAL类似
OP_INVOKE_SUPER_RANGE
vAA,vCCCC
与OP_INVOKE_VIRTUAL_RANGE类似,不过检验的是超类的方法
OP_INVOKE_SUPER
与OP_INVOKE_VIRTUAL类似,不过检验的是超类的方法
OP_INVOKE_DIRECT_RANGE
vAA,vCCCC
与OP_INVOKE_VIRTUAL_RANGE类似,不过检验的是超类的方法
OP_INVOKE_DIRECT
与OP_INVOKE_VIRTUAL类似,不过检验的是超类的方法
OP_INVOKE_STATIC_RANGE
vAA,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
OP_RETURN_WIDE
vAA
retval.j=*((long*)&v[vAA])
OP_RETURN_VOID
不做什么事
OP_RETURN
OP_RETURN_OBJECT
vAA
retval.i=*((long*)&v[vAA])