日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

用Java实现JVM第五章《指令集和解释器》

發布時間:2023/12/31 java 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用Java实现JVM第五章《指令集和解释器》 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

案例介紹
本案例通過java代碼實現jvm規范中指令集和解釋器,完成后就可以開始執行1到100的加和計算。

Java虛擬機顧名思義,就是一臺虛擬的機器,而字節碼(bytecode)就是運行在這臺虛擬機器上的機器碼。我們已經知道,每一個類或者接口都會被Java編譯器編譯成一個class文件,類或接口的方法信息就放在class文件的method_info結構中。如果方法不是抽象的,也不是本地方法,方法的Java代碼就會被編譯器編譯成字節碼(即使方法是空的,編譯器也會生成一條return語句),存在method_info結構的Code屬性中。

環境準備
1、jdk 1.8.0
2、IntelliJ IDEA Community Edition 2018.3.1 x64

配置信息
1、調試配置
2.1、配置位置:Run/Debug Configurations -> program arguments
2.2、配置內容:-Xjre “C:\Program Files\Java\jdk1.8.0_161\jre” E:\itstack\git\istack-demo\itstack-demo-jvm\itstack-demo-jvm-05\target\test-classes\org\itstack\demo\test\HelloWorld

代碼示例

itstack-demo-jvm-05 ├── pom.xml └── src└── main│ └── java│ └── org.itstack.demo.jvm│ ├── classfile│ │ ├── attributes {BootstrapMethods/Code/ConstantValue...}│ │ ├── constantpool {CONSTANT_TAG_CLASS/CONSTANT_TAG_FIELDREF/CONSTANT_TAG_METHODREF...}│ │ ├── ClassFile.java│ │ ├── ClassReader.java│ │ └── MemberInfo.java │ ├── classpath│ │ ├── impl│ │ │ ├── CompositeEntry.java│ │ │ ├── DirEntry.java │ │ │ ├── WildcardEntry.java │ │ │ └── ZipEntry.java │ │ ├── Classpath.java│ │ └── Entry.java │ ├── classpath│ │ ├── base│ │ ├── comparisons│ │ ├── constants│ │ ├── control│ │ ├── conversions│ │ ├── extended│ │ ├── loads│ │ ├── math│ │ │ ├── add│ │ │ ├── and│ │ │ ├── div│ │ │ ├── iinc│ │ │ ├── mul│ │ │ ├── neg│ │ │ ├── or│ │ │ ├── rem│ │ │ ├── sh│ │ │ ├── sub│ │ │ └── xor│ │ ├── stack│ │ ├── store│ │ └── Factory │ ├── rtda│ │ ├── Frame.java│ │ ├── JvmStack.java│ │ ├── LocalVars.java│ │ ├── OperandStack.java│ │ ├── Slot.java │ │ └── Thread.java│ ├── Cmd.java│ ├── Interpret.java │ └── Main.java└── test└── java└── org.itstack.demo.test└── HelloWorld.java

Factory.java

public class Factory {public static Instruction newInstruction(byte opcode) {switch (opcode) {case 0x00:return new NOP();case 0x01:return new ACONST_NULL();case 0x02:return new ICONST_M1();case 0x03:return new ICONST_0();case 0x04:return new ICONST_1();case 0x05:return new ICONST_2();case 0x06:return new ICONST_3();case 0x07:return new ICONST_4();case 0x08:return new ICONST_5();case 0x09:return new LCONST_0();case 0x0a:return new LCONST_1();case 0x0b:return new FCONST_0();case 0x0c:return new FCONST_1();case 0x0d:return new FCONST_2();case 0x0e:return new DCONST_0();case 0x0f:return new DCONST_1();case 0x10:return new BIPUSH();case 0x11:return new SIPUSH();// case 0x12:// return &LDC{}// case 0x13:// return &LDC_W{}// case 0x14:// return &LDC2_W{}case 0x15:return new ILOAD();case 0x16:return new LLOAD();case 0x17:return new FLOAD();case 0x18:return new DLOAD();case 0x19:return new ALOAD();case 0x1a:return new ILOAD_0();case 0x1b:return new ILOAD_1();case 0x1c:return new ILOAD_2();case 0x1d:return new ILOAD_3();case 0x1e:return new LLOAD_0();case 0x1f:return new LLOAD_1();case 0x20:return new LLOAD_2();case 0x21:return new LLOAD_3();case 0x22:return new FLOAD_0();case 0x23:return new FLOAD_1();case 0x24:return new FLOAD_2();case 0x25:return new FLOAD_3();case 0x26:return new DLOAD_0();case 0x27:return new DLOAD_1();case 0x28:return new DLOAD_2();case 0x29:return new DLOAD_3();case 0x2a:return new ALOAD_0();case 0x2b:return new ALOAD_1();case 0x2c:return new ALOAD_2();case 0x2d:return new ALOAD_3();// case 0x2e:// return iaload// case 0x2f:// return laload// case 0x30:// return faload// case 0x31:// return daload// case 0x32:// return aaload// case 0x33:// return baload// case 0x34:// return caload// case 0x35:// return saloadcase 0x36:return new ISTORE();case 0x37:return new LSTORE();case 0x38:return new FSTORE();case 0x39:return new DSTORE();case 0x3a:return new ASTORE();case 0x3b:return new ISTORE_0();case 0x3c:return new ISTORE_1();case 0x3d:return new ISTORE_2();case 0x3e:return new ISTORE_3();case 0x3f:return new LSTORE_0();case 0x40:return new LSTORE_1();case 0x41:return new LSTORE_2();case 0x42:return new LSTORE_3();case 0x43:return new FSTORE_0();case 0x44:return new FSTORE_1();case 0x45:return new FSTORE_2();case 0x46:return new FSTORE_3();case 0x47:return new DSTORE_0();case 0x48:return new DSTORE_1();case 0x49:return new DSTORE_2();case 0x4a:return new DSTORE_3();case 0x4b:return new ASTORE_0();case 0x4c:return new ASTORE_1();case 0x4d:return new ASTORE_2();case 0x4e:return new ASTORE_3();// case 0x4f:// return iastore// case 0x50:// return lastore// case 0x51:// return fastore// case 0x52:// return dastore// case 0x53:// return aastore// case 0x54:// return bastore// case 0x55:// return castore// case 0x56:// return sastorecase 0x57:return new POP();case 0x58:return new POP2();case 0x59:return new DUP();case 0x5a:return new DUP_X1();case 0x5b:return new DUP_X2();case 0x5c:return new DUP2();case 0x5d:return new DUP2_X1();case 0x5e:return new DUP2_X2();case 0x5f:return new SWAP();case 0x60:return new IADD();case 0x61:return new LADD();case 0x62:return new FADD();case 0x63:return new DADD();case 0x64:return new ISUB();case 0x65:return new LSUB();case 0x66:return new FSUB();case 0x67:return new DSUB();case 0x68:return new IMUL();case 0x69:return new LMUL();case 0x6a:return new FMUL();case 0x6b:return new DMUL();case 0x6c:return new IDIV();case 0x6d:return new LDIV();case 0x6e:return new FDIV();case 0x6f:return new DDIV();case 0x70:return new IREM();case 0x71:return new LREM();case 0x72:return new FREM();case 0x73:return new DREM();case 0x74:return new INEG();case 0x75:return new LNEG();case 0x76:return new FNEG();case 0x77:return new DNEG();case 0x78:return new ISHL();case 0x79:return new LSHL();case 0x7a:return new ISHR();case 0x7b:return new LSHR();case 0x7c:return new IUSHR();case 0x7d:return new LUSHR();case 0x7e:return new IAND();case 0x7f:return new LAND();case (byte) 0x80:return new IOR();case (byte) 0x81:return new LOR();case (byte) 0x82:return new IXOR();case (byte) 0x83:return new LXOR();case (byte) 0x84:return new IINC();case (byte) 0x85:return new I2L();case (byte) 0x86:return new I2F();case (byte) 0x87:return new I2D();case (byte) 0x88:return new L2I();case (byte) 0x89:return new L2F();case (byte) 0x8a:return new L2D();case (byte) 0x8b:return new F2I();case (byte) 0x8c:return new F2L();case (byte) 0x8d:return new F2D();case (byte) 0x8e:return new D2I();case (byte) 0x8f:return new D2L();case (byte) 0x90:return new D2F();case (byte) 0x91:return new I2B();case (byte) 0x92:return new I2C();case (byte) 0x93:return new I2S();case (byte) 0x94:return new LCMP();case (byte) 0x95:return new FCMPL();case (byte) 0x96:return new FCMPG();case (byte) 0x97:return new DCMPL();case (byte) 0x98:return new DCMPG();case (byte) 0x99:return new IFEQ();case (byte) 0x9a:return new IFNE();case (byte) 0x9b:return new IFLT();case (byte) 0x9c:return new IFGE();case (byte) 0x9d:return new IFGT();case (byte) 0x9e:return new IFLE();case (byte) 0x9f:return new IF_ICMPEQ();case (byte) 0xa0:return new IF_ICMPNE();case (byte) 0xa1:return new IF_ICMPLT();case (byte) 0xa2:return new IF_ICMPGE();case (byte) 0xa3:return new IF_ICMPGT();case (byte) 0xa4:return new IF_ICMPLE();case (byte) 0xa5:return new IF_ACMPEQ();case (byte) 0xa6:return new IF_ACMPNE();case (byte) 0xa7:return new GOTO();// case 0xa8:// return &JSR{}// case 0xa9:// return &RET{}case (byte) 0xaa:return new TABLE_SWITCH();case (byte) 0xab:return new LOOKUP_SWITCH();// case 0xac:// return ireturn// case 0xad:// return lreturn// case 0xae:// return freturn// case 0xaf:// return dreturn// case 0xb0:// return areturn// case 0xb1:// return _return// case 0xb2:// return &GET_STATIC{}// case 0xb3:// return &PUT_STATIC{}// case 0xb4:// return &GET_FIELD{}// case 0xb5:// return &PUT_FIELD{}// case 0xb6:// return &INVOKE_VIRTUAL{}// case 0xb7:// return &INVOKE_SPECIAL{}// case 0xb8:// return &INVOKE_STATIC{}// case 0xb9:// return &INVOKE_INTERFACE{}// case 0xba:// return &INVOKE_DYNAMIC{}// case 0xbb:// return &NEW{}// case 0xbc:// return &NEW_ARRAY{}// case 0xbd:// return &ANEW_ARRAY{}// case 0xbe:// return arraylength// case 0xbf:// return athrow// case 0xc0:// return &CHECK_CAST{}// case 0xc1:// return &INSTANCE_OF{}// case 0xc2:// return monitorenter// case 0xc3:// return monitorexitcase (byte) 0xc4:return new WIDE();// case 0xc5:// return &MULTI_ANEW_ARRAY{}case (byte) 0xc6:return new IFNULL();case (byte) 0xc7:return new IFNONNULL();case (byte) 0xc8:return new GOTO_W();// case 0xc9:// return &JSR_W{}// case 0xca: breakpoint// case 0xfe: impdep1// case 0xff: impdep2default:return null;}}}

Interpret.java

//指令集解釋器 class Interpret {Interpret(MemberInfo m) {CodeAttribute codeAttr = m.codeAttribute();int maxLocals = codeAttr.maxLocals();int maxStack = codeAttr.maxStack();byte[] byteCode = codeAttr.data();Thread thread = new Thread();Frame frame = thread.newFrame(maxLocals, maxStack);thread.pushFrame(frame);loop(thread, byteCode);}private void loop(Thread thread, byte[] byteCode) {Frame frame = thread.popFrame();BytecodeReader reader = new BytecodeReader();while (true) {//循環int pc = frame.nextPC();thread.setPC(pc);//decodereader.reset(byteCode, pc);byte opcode = reader.readByte();Instruction inst = Factory.newInstruction(opcode);if (null == inst) {System.out.println("寄存器(指令)尚未實現 " + byteToHexString(new byte[]{opcode}));break;}inst.fetchOperands(reader);frame.setNextPC(reader.pc());System.out.println("寄存器(指令):" + byteToHexString(new byte[]{opcode}) + " -> " + inst.getClass().getSimpleName() + " => 局部變量表:" + JSON.toJSONString(frame.operandStack().getSlots()) + " 操作數棧:" + JSON.toJSONString(frame.operandStack().getSlots())); //execinst.execute(frame);}}private static String byteToHexString(byte[] codes) {StringBuilder sb = new StringBuilder();sb.append("0x");for (byte b : codes) {int value = b & 0xFF;String strHex = Integer.toHexString(value);if (strHex.length() < 2) {strHex = "0" + strHex;}sb.append(strHex);}return sb.toString();}}

HelloWorld.java

package org.itstack.demo.test;public class HelloWorld {public static void main(String[] args) {int sum = 0;for (int i = 1; i <= 100; i++) {sum += i;}System.out.println(sum);}}

測試結果 {此時還不能輸出結果,但是在操作數據棧中已經可以看到結果:5050}

"C:\Program Files\Java\jdk1.8.0_161\bin\java.exe" "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2018.3.1\lib\idea_rt.jar=61887:D:\Program Files\JetBrains\IntelliJ IDEA Community Edition 2018.3.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_161\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\rt.jar;E:\itstack\git\istack-demo\itstack-demo-jvm\itstack-demo-jvm-05\target\classes;D:\Program Files (x86)\apache-maven-2.2.1\repository\com\beust\jcommander\1.72\jcommander-1.72.jar;D:\Program Files (x86)\apache-maven-2.2.1\repository\org\projectlombok\lombok\1.18.0\lombok-1.18.0.jar;D:\Program Files (x86)\apache-maven-2.2.1\repository\com\alibaba\fastjson\1.2.40\fastjson-1.2.40.jar" org.itstack.demo.jvm.Main -Xjre "C:\Program Files\Java\jdk1.8.0_161\jre" E:\itstack\git\istack-demo\itstack-demo-jvm\itstack-demo-jvm-05\target\test-classes\org\itstack\demo\test\HelloWorld classpath:org.itstack.demo.jvm.classpath.Classpath@4bf558aa class:E:\itstack\git\istack-demo\itstack-demo-jvm\itstack-demo-jvm-05\target\test-classes\org\itstack\demo\test\HelloWorld args:null 寄存器(指令):0x03 -> ICONST_0 => 局部變量表:[{"num":0},{"num":0}] 操作數棧:[{"num":0},{"num":0}] 寄存器(指令):0x3c -> ISTORE_1 => 局部變量表:[{"num":0},{"num":0}] 操作數棧:[{"num":0},{"num":0}] 寄存器(指令):0x04 -> ICONST_1 => 局部變量表:[{"num":0},{"num":0}] 操作數棧:[{"num":0},{"num":0}] 寄存器(指令):0x3d -> ISTORE_2 => 局部變量表:[{"num":1},{"num":0}] 操作數棧:[{"num":1},{"num":0}] 寄存器(指令):0x1c -> ILOAD_2 => 局部變量表:[{"num":1},{"num":0}] 操作數棧:[{"num":1},{"num":0}] 寄存器(指令):0x10 -> BIPUSH => 局部變量表:[{"num":1},{"num":0}] 操作數棧:[{"num":1},{"num":0}] 寄存器(指令):0xa3 -> IF_ICMPGT => 局部變量表:[{"num":1},{"num":100}] 操作數棧:[{"num":1},{"num":100}] 寄存器(指令):0x1b -> ILOAD_1 => 局部變量表:[{"num":1},{"num":100}] 操作數棧:[{"num":1},{"num":100}] 寄存器(指令):0x1c -> ILOAD_2 => 局部變量表:[{"num":0},{"num":100}] 操作數棧:[{"num":0},{"num":100}]... ...寄存器(指令):0x60 -> IADD => 局部變量表:[{"num":4950},{"num":100}] 操作數棧:[{"num":4950},{"num":100}] 寄存器(指令):0x3c -> ISTORE_1 => 局部變量表:[{"num":5050},{"num":100}] 操作數棧:[{"num":5050},{"num":100}] 寄存器(指令):0x84 -> IINC => 局部變量表:[{"num":5050},{"num":100}] 操作數棧:[{"num":5050},{"num":100}] 寄存器(指令):0xa7 -> GOTO => 局部變量表:[{"num":5050},{"num":100}] 操作數棧:[{"num":5050},{"num":100}] 寄存器(指令):0x1c -> ILOAD_2 => 局部變量表:[{"num":5050},{"num":100}] 操作數棧:[{"num":5050},{"num":100}] 寄存器(指令):0x10 -> BIPUSH => 局部變量表:[{"num":101},{"num":100}] 操作數棧:[{"num":101},{"num":100}] 寄存器(指令):0xa3 -> IF_ICMPGT => 局部變量表:[{"num":101},{"num":100}] 操作數棧:[{"num":101},{"num":100}] 寄存器(指令)尚未實現 0xb2Process finished with exit code 0

總結

以上是生活随笔為你收集整理的用Java实现JVM第五章《指令集和解释器》的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。