Skip to content

erl实现简单Javap功能反编译 bytecode,目的是为了学习java字节码解释和命令

License

Notifications You must be signed in to change notification settings

xiaodya/erljavap

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

erljavap

erl实现简单Javap功能反编译 bytecode,目的是为了学习java字节码解释和命令

An OTP application

Build

$ rebar3 compile

Summary of ByteCode

  • 4 bytes|Magic Number
  • 2+2 bytes|Version minor_version+major_version
  • 2+n bytes|Constant Pool 2 bytes is contsant length . see bytecode.hrl marco define
  • 2 bytes|Access Flags
  • 2 bytes|This Class Name
  • 2 bytes|Super Class Name
  • 2+n bytes|Interfaces
  • 2+n bytes|Fields
  • 2+n bytes|Methods
  • 2+n bytes|Attributes

Summary of OpCode

  • | 指令码 | 助记符 | 操作数|说明 |

  • | --- | --- | --- |

  • |0x00|nop|无|什么都不做|

  • |0x01|aconst_null|无|将null推送至栈顶|

  • |0x02|iconst_m1|无|将int型-1推送至栈顶|

  • |0x03|iconst_0|无|将int常量0推送至栈顶|

  • |0x04|iconst_1|无|将int常量1推送至栈顶|

  • |0x05|iconst_2|无|将int常量2推送至栈顶|

  • |0x06|iconst_3|无|将int常量3推送至栈顶|

  • |0x07|iconst_4|无|将int常量4推送至栈顶|

  • |0x08|iconst_5|无|将int常量5推送至栈顶|

  • |0x09|lconst_0|无|将long常量0推送至栈顶|

  • |0x0a|lconst_1|无|将long常量1推送至栈顶|

  • |0x0b|fconst_0|无|将float常量0推送至栈顶|

  • |0x0c|fconst_1|无|将float常量1推送至栈顶|

  • |0x0d|fconst_2|无|将float常量2推送至栈顶|

  • |0x0e|dconst_0|无|将double常量0推送至栈顶|

  • |0x0f|dconst_1|无|将double常量1推送至栈顶|

  • |0x10|bipush|byte类型操作数|将单字节的常量值(-128~127)推送至栈顶|

  • |0x11|sipush|int类型操作数|将一个短整型常量值(-32768~32767)推送至栈顶|

  • |0x12|ldc|常量编号|将int, float或String型常量值从常量池中推送至栈顶|

  • |0x13|ldc_w|常量编号|将int, float或String型常量值从常量池中推送至栈顶(宽索引)|

  • |0x14|ldc2_w|常量编号|将long或double型常量值从常量池中推送至栈顶(宽索引)|

  • |0x15|iload|vindex|将位置为vindex的int类型的局部变量压入栈|

  • |0x16|lload|vindex|将位置为vindex和(vindex+1)的long类型的局部变量压入栈|

  • |0x17|fload|vindex|将位置为vindex的float类型的局部变量压入栈|

  • |0x18|dload|vindex|将位置为vindex和(vindex+1)的double类型的局部变量压入栈|

  • |0x19|aload|vindex|将位置为vindex的对象引用局部变量压入栈|

  • |0x1a|iload_0|无|将位置为0的int类型的局部变量压入栈|

  • |0x1b|iload_1|无|将位置为1的int类型的局部变量压入栈|

  • |0x1c|iload_2|无|将位置为2的int类型的局部变量压入栈|

  • |0x1d|iload_3|无|将位置为3的int类型的局部变量压入栈|

  • |0x1e|lload_0|无|将位置为0和1的long类型的局部变量压入栈|

  • |0x1f|lload_1|无|将位置为1和2的long类型的局部变量压入栈|

  • |0x20|lload_2|无|将位置为2和3的long类型的局部变量压入栈|

  • |0x21|lload_3|无|将位置为3和4的long类型的局部变量压入栈|

  • |0x22|fload_0|无|将本地变量表的第一个float型本地变量推送至栈顶|

  • |0x23|fload_1|无|将本地变量表的第二个float型本地变量推送至栈顶|

  • |0x24|fload_2|无|将本地变量表的第三个float型本地变量推送至栈顶|

  • |0x25|fload_3|无|将本地变量表的第四个float型本地变量推送至栈顶|

  • |0x26|dload_0|无|将本地变量表的第一个double型本地变量推送至栈顶|

  • |0x27|dload_1|无|将本地变量表的第二个double型本地变量推送至栈顶|

  • |0x28|dload_2|无|将本地变量表的第三个double型本地变量推送至栈顶|

  • |0x29|dload_3|无|将本地变量表的第四个double型本地变量推送至栈顶|

  • |0x2a|aload_0|无|将引用类型变量推送至栈顶,非静态方法中 表示对this的操作,静态方法中表示对方法的第一参数的操作|

  • |0x2b|aload_1|无|将本地变量表的第二个引用类型本地变量推送至栈顶|

  • |0x2c|aload_2|无|将本地变量表的第三个引用类型本地变量推送至栈顶|

  • |0x2d|aload_3|无|将本地变量表的第四个引用类型本地变量推送至栈顶|

  • |0x2e|iaload|无|将int型数组指定索引的值推送至栈顶|

  • |0x2f|laload|无|将long型数组指定索引的值推送至栈顶|

  • |0x30|faload|无|将float型数组指定索引的值推送至栈顶|

  • |0x31|daload|无|将double型数组指定索引的值推送至栈顶|

  • |0x32|aaload|无|将引用型数组指定索引的值推送至栈顶|

  • |0x33|baload|无|将boolean或byte型数组指定索引的值推送至栈顶|

  • |0x34|caload|无|将char型数组指定索引的值推送至栈顶|

  • |0x35|saload|无|将short型数组指定索引的值推送至栈顶|

  • |0x36|istore|无|将栈顶int型数值存入指定本地变量|

  • |0x37|lstore|无|将栈顶long型数值存入指定本地变量|

  • |0x38|fstore|无|将栈顶float型数值存入指定本地变量|

  • |0x39|dstore|无|将栈顶double型数值存入指定本地变量|

  • |0x3a|astore|无|将栈顶引用型数值存入指定本地变量|

  • |0x3b|istore_0|无|将栈顶int型数值存入第一个本地变量|

  • |0x3c|istore_1|无|将栈顶int型数值存入第二个本地变量|

  • |0x3d|istore_2|无|将栈顶int型数值存入第三个本地变量|

  • |0x3e|istore_3|无|将栈顶int型数值存入第四个本地变量|

  • |0x3f|lstore_0|无|将栈顶long型数值存入第一个本地变量|

  • |0x40|lstore_1|无|将栈顶long型数值存入第二个本地变量|

  • |0x41|lstore_2|无|将栈顶long型数值存入第三个本地变量|

  • |0x42|lstore_3|无|将栈顶long型数值存入第四个本地变量|

  • |0x43|fstore_0|无|将栈顶float型数值存入第一个本地变量|

  • |0x44|fstore_1|无|将栈顶float型数值存入第二个本地变量|

  • |0x45|fstore_2|无|将栈顶float型数值存入第三个本地变量|

  • |0x46|fstore_3|无|将栈顶float型数值存入第四个本地变量|

  • |0x47|dstore_0|无|将栈顶double型数值存入第一个本地变量|

  • |0x48|dstore_1|无|将栈顶double型数值存入第二个本地变量|

  • |0x49|dstore_2|无|将栈顶double型数值存入第三个本地变量|

  • |0x4a|dstore_3|无|将栈顶double型数值存入第四个本地变量|

  • |0x4b|astore_0|无|将栈顶引用型数值存入第一个本地变量|

  • |0x4c|astore_1|无|将栈顶引用型数值存入第二个本地变量|

  • |0x4d|astore_2|无|将栈顶引用型数值存入第三个本地变量|

  • |0x4e|astore_3|无|将栈顶引用型数值存入第四个本地变量|

  • |0x4f|iastore|无|将栈顶int型数值存入指定数组的指定索引位置|

  • |0x50|lastore|无|将栈顶long型数值存入指定数组的指定索引位置|

  • |0x51|fastore|无|将栈顶float型数值存入指定数组的指定索引位置|

  • |0x52|dastore|无|将栈顶double型数值存入指定数组的指定索引位置|

  • |0x53|aastore|无|将栈顶引用型数值存入指定数组的指定索引位置|

  • |0x54|bastore|无|将栈顶boolean或byte型数值存入指定数组的指定索引位置|

  • |0x55|castore|无|将栈顶char型数值存入指定数组的指定索引位置|

  • |0x56|sastore|无|将栈顶short型数值存入指定数组的指定索引位置|

  • |0x57|pop|无|将栈顶数值弹出 (数值不能是long或double类型的)|

  • |0x58|pop2|无|将栈顶的一个(long或double类型的)或两个数值弹出(其它)|

  • |0x59|dup|复制栈顶数值并将复制值压入栈顶|

  • |0x5a|dup_x1|复制栈顶数值并将两个复制值压入栈顶|

  • |0x5b|dup_x2|复制栈顶数值并将三个(或两个)复制值压入栈顶|

  • |0x5c|dup2|复制栈顶一个(long或double类型的)或两个(其它)数值并将复制值压入栈顶|

  • |0x5d|dup2_x1|<待补充>|

  • |0x5e|dup2_x2|<待补充>|

  • |0x5f|swap|无|将栈最顶端的两个数值互换(数值不能是long或double类型的)|

  • |0x60|iadd|无|将栈顶两int型数值相加并将结果压入栈顶|

  • |0x61|ladd|无|将栈顶两long型数值相加并将结果压入栈顶|

  • |0x62|fadd|无|将栈顶两float型数值相加并将结果压入栈顶|

  • |0x63|dadd|无|将栈顶两double型数值相加并将结果压入栈顶|

  • |0x64|isub|无|将栈顶两int型数值相减并将结果压入栈顶|

  • |0x65|lsub|无|将栈顶两long型数值相减并将结果压入栈顶|

  • |0x66|fsub|无|将栈顶两float型数值相减并将结果压入栈顶|

  • |0x67|dsub|无|将栈顶两double型数值相减并将结果压入栈顶|

  • |0x68|imul|无|将栈顶两int型数值相乘并将结果压入栈顶|

  • |0x69|lmul|无|将栈顶两long型数值相乘并将结果压入栈顶|

  • |0x6a|fmul|无|将栈顶两float型数值相乘并将结果压入栈顶|

  • |0x6b|dmul|无|将栈顶两double型数值相乘并将结果压入栈顶|

  • |0x6c|idiv|无|将栈顶两int型数值相除并将结果压入栈顶|

  • |0x6d|ldiv|无|将栈顶两long型数值相除并将结果压入栈顶|

  • |0x6e|fdiv|无|将栈顶两float型数值相除并将结果压入栈顶|

  • |0x6f|ddiv|无|将栈顶两double型数值相除并将结果压入栈顶|

  • |0x70|irem|无|将栈顶两int型数值作取模运算并将结果压入栈顶|

  • |0x71|lrem|无|将栈顶两long型数值作取模运算并将结果压入栈顶|

  • |0x72|frem|无|将栈顶两float型数值作取模运算并将结果压入栈顶|

  • |0x73|drem|无|将栈顶两double型数值作取模运算并将结果压入栈顶|

  • |0x74|ineg|无|将栈顶int型数值取负并将结果压入栈顶|

  • |0x75|lneg|无|将栈顶long型数值取负并将结果压入栈顶|

  • |0x76|fneg|无|将栈顶float型数值取负并将结果压入栈顶|

  • |0x77|dneg|无|将栈顶double型数值取负并将结果压入栈顶|

  • |0x78|ishl|无|将int型数值左移位指定位数并将结果压入栈顶|

  • |0x79|lshl|无|将long型数值左移位指定位数并将结果压入栈顶|

  • |0x7a|ishr|无|将int型数值右(符号)移位指定位数并将结果压入栈顶|

  • |0x7b|lshr|无|将long型数值右(符号)移位指定位数并将结果压入栈顶|

  • |0x7c|iushr|无|将int型数值右(无符号)移位指定位数并将结果压入栈顶|

  • |0x7d|lushr|无|将long型数值右(无符号)移位指定位数并将结果压入栈顶|

  • |0x7e|iand|无|将栈顶两int型数值作“按位与”并将结果压入栈顶|

  • |0x7f|land|无|将栈顶两long型数值作“按位与”并将结果压入栈顶|

  • |0x80|ior|无|将栈顶两int型数值作“按位或”并将结果压入栈顶|

  • |0x81|lor|无|将栈顶两long型数值作“按位或”并将结果压入栈顶|

  • |0x82|ixor|无|将栈顶两int型数值作“按位异或”并将结果压入栈顶|

  • |0x83|lxor|无|将栈顶两long型数值作“按位异或”并将结果压入栈顶|

  • |0x84|iinc|无|将指定int型变量增加指定值(i++, i--, i+=2)|

  • |0x85|i2l|无|将栈顶int型数值强制转换成long型数值并将结果压入栈顶|

  • |0x86|i2f|无|将栈顶int型数值强制转换成float型数值并将结果压入栈顶|

  • |0x87|i2d|无|将栈顶int型数值强制转换成double型数值并将结果压入栈顶|

  • |0x88|l2i|无|将栈顶long型数值强制转换成int型数值并将结果压入栈顶|

  • |0x89|l2f|无|将栈顶long型数值强制转换成float型数值并将结果压入栈顶|

  • |0x8a|l2d|无|将栈顶long型数值强制转换成double型数值并将结果压入栈顶|

  • |0x8b|f2i|无|将栈顶float型数值强制转换成int型数值并将结果压入栈顶|

  • |0x8c|f2l|无|将栈顶float型数值强制转换成long型数值并将结果压入栈顶|

  • |0x8d|f2d|无|将栈顶float型数值强制转换成double型数值并将结果压入栈顶|

  • |0x8e|d2i|无|将栈顶double型数值强制转换成int型数值并将结果压入栈顶|

  • |0x8f|d2l|无|将栈顶double型数值强制转换成long型数值并将结果压入栈顶|

  • |0x90|d2f|无|将栈顶double型数值强制转换成float型数值并将结果压入栈顶|

  • |0x91|i2b|无|将栈顶int型数值强制转换成byte型数值并将结果压入栈顶|

  • |0x92|i2c|无|将栈顶int型数值强制转换成char型数值并将结果压入栈顶|

  • |0x93|i2s|无|将栈顶int型数值强制转换成short型数值并将结果压入栈顶|

  • |0x94|lcmp||比较栈顶两long型数值大小,并将结果(1,0,-1)压入栈顶|

  • |0x95|fcmpl||比较栈顶两float型数值大小,并将结果(1,0,-1)压入栈顶;当其中一个数值为NaN时,将-1压入栈顶|

  • |0x96|fcmpg||比较栈顶两float型数值大小,并将结果(1,0,-1)压入栈顶;当其中一个数值为NaN时,将1压入栈顶|

  • |0x97|dcmpl||比较栈顶两double型数值大小,并将结果(1,0,-1)压入栈顶;当其中一个数值为NaN时,将-1压入栈顶|

  • |0x98|dcmpg||比较栈顶两double型数值大小,并将结果(1,0,-1)压入栈顶;当其中一个数值为NaN时,将1压入栈顶|

  • |0x99|ifeq||当栈顶int型数值等于0时跳转|

  • |0x9a|ifne||当栈顶int型数值不等于0时跳转|

  • |0x9b|iflt||当栈顶int型数值小于0时跳转|

  • |0x9c|ifge||当栈顶int型数值大于等于0时跳转|

  • |0x9d|ifgt||当栈顶int型数值大于0时跳转|

  • |0x9e|ifle||当栈顶int型数值小于等于0时跳转|

  • |0x9f|if_icmpeq||比较栈顶两int型数值大小,当结果等于0时跳转|

  • |0xa0|if_icmpne||比较栈顶两int型数值大小,当结果不等于0时跳转|

  • |0xa1|if_icmplt||比较栈顶两int型数值大小,当结果小于0时跳转|

  • |0xa2|if_icmpge||比较栈顶两int型数值大小,当结果大于等于0时跳转|

  • |0xa3|if_icmpgt||比较栈顶两int型数值大小,当结果大于0时跳转|

  • |0xa4|if_icmple||比较栈顶两int型数值大小,当结果小于等于0时跳转|

  • |0xa5|if_acmpeq||比较栈顶两引用型数值,当结果相等时跳转|

  • |0xa6|if_acmpne||比较栈顶两引用型数值,当结果不相等时跳转|

  • |0xa7|goto||无条件跳转|

  • |0xa8|jsr||跳转至指定16位offset位置,并将jsr下一条指令地址压入栈顶|

  • |0xa9|ret||返回至本地变量指定的index的指令位置(一般与jsr, jsr_w联合使用)|

  • |0xaa|tableswitch||用于switch条件跳转,case值连续(可变长度指令)|

  • |0xab|lookupswitch||用于switch条件跳转,case值不连续(可变长度指令)|

  • |0xac|ireturn||从当前方法返回int|

  • |0xad|lreturn||从当前方法返回long|

  • |0xae|freturn||从当前方法返回float|

  • |0xaf|dreturn||从当前方法返回double|

  • |0xb0|areturn||从当前方法返回对象引用|

  • |0xb1|return||从当前方法返回void|

  • |0xb2|getstatic||获取指定类的静态域,并将其值压入栈顶|

  • |0xb3|putstatic||为指定的类的静态域赋值|

  • |0xb4|getfield||获取指定类的实例变量,并将其值压入栈顶|

  • |0xb5|putfield||为指定的类的实例变量赋值|

  • |0xb6|invokevirtual||调用实例方法|

  • |0xb7|invokespecial||调用超类构造方法,实例初始化方法,私有方法|

  • |0xb8|invokestatic||调用静态方法|

  • |0xb9|invokeinterface||调用接口方法|

  • |0xbb|new||创建一个对象,并将其引用值压入栈顶|

  • |0xbc|newarray||创建一个指定原始类型(如int, float, char…)的数组,并将其引用值压入栈顶|

  • |0xbd|anewarray||创建一个引用型(如类,接口,数组)的数组,并将其引用值压入栈顶|

  • |0xbe|arraylength||获得数组的长度值并压入栈顶|

  • |0xbf|athrow|无|将栈顶的异常抛出|

  • |0xc0|checkcast||检验类型转换,检验未通过将抛出ClassCastException|

  • |0xc1|instanceof||检验对象是否是指定的类的实例,如果是将1压入栈顶,否则将0压入栈顶|

  • |0xc2|monitorenter||获得对象的锁,用于同步方法或同步块|

  • |0xc3|monitorexit||释放对象的锁,用于同步方法或同步块|

  • |0xc4|wide||<待补充>|

  • |0xc5|multianewarray||创建指定类型和指定维度的多维数组(执行该指令时,操作栈中必须包含各维度的长度值),并将其引用值压入栈顶|

  • |0xc6|ifnull||为null时跳转|

  • |0xc7|ifnonnull||不为null时跳转|

  • |0xc8|goto_w||无条件跳转(宽索引)|

  • JVM指令助记符

  • 变量到操作数栈:iload,iload_,lload,lload_,fload,fload_,dload,dload_,aload,aload_

  • 操作数栈到变量:istore,istore_,lstore,lstore_,fstore,fstore_,dstore,dstor_,astore,astore_

  • 常数到操作数栈:bipush,sipush,ldc,ldc_w,ldc2_w,aconst_null,iconst_ml,iconst_,lconst_,fconst_,dconst_

  • 加:iadd,ladd,fadd,dadd

  • 减:isub,lsub,fsub,dsub

  • 乘:imul,lmul,fmul,dmul

  • 除:idiv,ldiv,fdiv,ddiv

  • 余数:irem,lrem,frem,drem

  • 取负:ineg,lneg,fneg,dneg

  • 移位:ishl,lshr,iushr,lshl,lshr,lushr

  • 按位或:ior,lor

  • 按位与:iand,land

  • 按位异或:ixor,lxor

  • 类型转换:i2l,i2f,i2d,l2f,l2d,f2d(放宽数值转换)

  • i2b,i2c,i2s,l2i,f2i,f2l,d2i,d2l,d2f(缩窄数值转换)

  • 创建类实便:new

  • 创建新数组:newarray,anewarray,multianwarray

  • 访问类的域和类实例域:getfield,putfield,getstatic,putstatic

  • 把数据装载到操作数栈:baload,caload,saload,iaload,laload,faload,daload,aaload

  • 从操作数栈存存储到数组:bastore,castore,sastore,iastore,lastore,fastore,dastore,aastore

  • 获取数组长度:arraylength

  • 检相类实例或数组属性:instanceof,checkcast

  • 操作数栈管理:pop,pop2,dup,dup2,dup_xl,dup2_xl,dup_x2,dup2_x2,swap

  • 有条件转移:ifeq,iflt,ifle,ifne,ifgt,ifge,ifnull,ifnonnull,if_icmpeq,if_icmpene, if_icmplt,if_icmpgt,if_icmple,if_icmpge,if_acmpeq,if_acmpne,lcmp,fcmpl fcmpg,dcmpl,dcmpg

  • 复合条件转移:tableswitch,lookupswitch

  • 无条件转移:goto,goto_w,jsr,jsr_w,ret

  • 调度对象的实便方法:invokevirtual

  • 调用由接口实现的方法:invokeinterface

  • 调用需要特殊处理的实例方法:invokespecial

  • 调用命名类中的静态方法:invokestatic

  • 方法返回:ireturn,lreturn,freturn,dreturn,areturn,return

  • 异常:athrow

  • finally关键字的实现使用:jsr,jsr_w,ret

About

erl实现简单Javap功能反编译 bytecode,目的是为了学习java字节码解释和命令

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages