栈的增长方向以及某一瞬时可能的数据结构表示 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])
Dalvik opcodes
最新推荐文章于 2023-02-28 17:20:57 发布