新手学做网站pdfwordpress外贸建站怎么加左侧边栏
news/
2025/9/24 0:26:59/
文章来源:
新手学做网站pdf,wordpress外贸建站怎么加左侧边栏,搜索引擎营销怎么做,网站做多长时间才会逐渐成功字节码指令简介
Java虚拟机指令由操作码#xff08;Opcode#xff09;和跟随其后的零至多个操作数#xff08;Operand#xff09;组成。 操作码#xff1a;一个字节长度的#xff0c;代表某种特定操作含义的数字。 操作数#xff1a;操作码需要的参数。
字节码与数据…字节码指令简介
Java虚拟机指令由操作码Opcode和跟随其后的零至多个操作数Operand组成。 操作码一个字节长度的代表某种特定操作含义的数字。 操作数操作码需要的参数。
字节码与数据类型
opcodebyteshortintlongfloatdoublecharreferenceTstoreistorelstorefstoredstoreastoreTinciincTaloadbaloadsaloadialoadlaloadfaloaddaloadcaloadaaloadTastorebastoresastoreiastorelastorefastoredastorecastoreastoreTaddiaddladdfadddaddTsubisublsubfsubdsubTmulimullmulfmuldmulTdividivldivfdivddivTremiremlremfremdremTnegineglnegfnegdnegTshlishllshlTshrishrlshrTushriushrlushrTandiandlandToriorlorTxorixorlxori2Ti2bi2si2li2fi2dl2Tl2il2fl2df2Tf2if2lf2dd2Td2id2ld2fTcmplcmpTcmplfcmpldcmplTcmpgfcmpgdcmpgif_TempOPif_iempOPif_aempOPTreturnireturnlreturnfreturndreturnareturn
大部分指令都没有支持整数类型byte、 char和short 没有任何指令支持boolean类型。 编译器会在编译期或运行期将byte和short类型的数据带符号扩展Sign-Extend 为相应的int类型数据 将boolean和char类型数据零位扩展Zero-Extend 为相应的int类型数据。 与之类似 在处理boolean、 byte、 short和char类型的数组时 也会转换为使用对应的int类型的字节码指令来处理。 因此 大多数对于boolean、 byte、 short和char类型数据的操作 实际上都是使用相应的对int类型作为运算类型Computational Type 来进行的。
加载和存储指令
加载和存储指令用于将数据在栈帧中的局部变量表和操作数栈之间来回传输 。 将一个局部变量加载到操作栈iload,iload_0,iload_1,iload_2,iload_3,lload,lload_0,lload_1,lload_2,lload_3,fload_0,fload_1,fload_2,fload_3,dload,dload_0,dload_1,dload_2,dload_3,aload,aload_0,aload_1,aload_2,aload_3 iload_0 表示将第0个变量槽中的int型变量推到操作数栈栈顶。 iload_1 表示将第1个变量槽中的int型变量推到操作数栈栈顶。 iload 后面会跟一个参数n表示将第n个变量槽中的int行变量推送到操作数栈栈顶。 其余的指令同理。 将一个数值从操作数栈存储到局部变量表中 istore、 istore_n、 lstore、 lstore_n、 fstore、fstore_n、 dstore、 dstore_n、 astore、 astore_n将一个常量加载到操作数栈 bipush、 sipush、 ldc、 ldc_w、 ldc2_w、 aconst_null、 iconst_m1、iconst_i、 lconst_l、 fconst_f、 dconst_d扩充局部变量表的访问索引的指令 wide #拓展本地变量的宽度用于修改其他指令行为 public class Test2{public int inc(int a,int b,int c,int d,int e,int f,int h,int j,int k){int z a 9;return z;}
}利用javac -g Test2.java编译该源文件再利用javap -v Test2.class反编译 public int inc(int, int, int, int, int, int, int, int, int);descriptor: (IIIIIIIII)Iflags: ACC_PUBLICCode:stack2, locals11, args_size100: iload_1 # 将第1个变量槽中的int型变量推送到栈顶即将变量a推送到栈顶1: bipush 9 # 将int型常量9推送到栈顶3: iadd # 将栈顶的两个int型数值相加并压入栈顶即a94: istore 10 # 将栈顶int型数值存入指定的本地变量槽及将a9的结果赋值给变量Z6: iload 10 # 将第10个变量槽中的变量推送值栈顶8: ireturn # 弹栈从当前方法返回int及return z;LineNumberTable:line 3: 0line 4: 6LocalVariableTable:Start Length Slot Name Signature0 9 0 this LTest2;0 9 1 a I0 9 2 b I0 9 3 c I0 9 4 d I0 9 5 e I0 9 6 f I0 9 7 h I0 9 8 j I0 9 9 k I6 3 10 z I运算指令
运算指令用于将操作数栈上的两个值进行某种特定的运算并将结果重新压入操作栈顶。可分为对整型数据进行运算的指令和对浮点型数据进行运算指令。
不存在直接支持byte、 short、 char和boolean类型的算术指令 而是使用操作int类型的指令代替。
#加法指令 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、 ishr、 iushr、 lshl、 lshr、 lushr
#按位或指令 ior、 lor
#按位与指令 iand、 land
#按位异或指令 ixor、 lxor
#局部变量自增指令 iinc
#比较指令 dcmpg、 dcmpl、 fcmpg、 fcmpl、 lcmp类型转换指令
类型转换指令可以将两种不同的数值类型相互转换 。
**宽化类型转换**小范围类型向大范围类型的安全转换。
以下数值类型的宽化类型转换无序显示的转换指令 1. int到longfloatdouble2. long到floatdouble3. float到double窄化类型转换窄化类型转换必须显示的使用转换指令来完成
i2b、i2c、i2s、l2i、f2i、f2l、d2i、d2l、d2f窄化转换可能会导致转换结果产生不同的正负号、不同的数量级的情况很可能会出现精度丢失。
JVM将浮点值转换为int或者long时需要遵循以下规则
如果浮点值是NaN 那转换结果就是int或long类型的0。如果浮点值不是无穷大的话 浮点值使用IEEE 754的向零舍入模式取整 获得整数值v。 如果v在目标类型Tint或long 的表示范围之类 那转换结果就是v 否则 将根据v的符号 转换为T所能表示的最大或者最小正数。
细节参看IEEE 754
对象创建与访问指令
·创建类实例的指令 new
·创建数组的指令 newarray、 anewarray、 multianewarray
·访问类字段static字段 或者称为类变量 和实例字段非static字段 或者称为实例变量的指令 getfield、 putfield、 getstatic、 putstatic
·把一个数组元素加载到操作数栈的指令 baload、 caload、 saload、 iaload、 laload、 faload、daload、 aaload
·将一个操作数栈的值储存到数组元素中的指令 bastore、 castore、 sastore、 iastore、 fastore、dastore、 aastore
·取数组长度的指令 arraylength
·检查类实例类型的指令 instanceof、 checkcast操作数栈管理指令
·将操作数栈的栈顶一个或两个元素出栈 pop、 pop2
·复制栈顶一个或两个数值并将复制值或双份的复制值重新压入栈顶 dup、 dup2、 dup_x1、dup2_x1、 dup_x2、 dup2_x2
·将栈最顶端的两个数值互换 swap控制转移指令
控制转移指令可以让Java虚拟机有条件或无条件地从指定位置指令而不是控制转移指令 的下一条指令继续执行程序 从概念模型上理解 可以认为控制指令就是在有条件或无条件地修改PC寄存器的值。
·条件分支 ifeq、 iflt、 ifle、 ifne、 ifgt、 ifge、 ifnull、 ifnonnull、 if_icmpeq、 if_icmpne、 if_icmplt、if_icmpgt、 if_icmple、 if_icmpge、 if_acmpeq和if_acmpne
·复合条件分支 tableswitch、 lookupswitch
·无条件分支 goto、 goto_w、 jsr、 jsr_w、 ret方法调用和返回指令
·invokevirtual指令 用于调用对象的实例方法 根据对象的实际类型进行分派虚方法分派 这也是Java语言中最常见的方法分派方式。
·invokeinterface指令 用于调用接口方法 它会在运行时搜索一个实现了这个接口方法的对象 找出适合的方法进行调用。
·invokespecial指令 用于调用一些需要特殊处理的实例方法 包括实例初始化方法、 私有方法和父类方法。
·invokestatic指令 用于调用类静态方法static方法 。
·invokedynamic指令 用于在运行时动态解析出调用点限定符所引用的方法。 并执行该方法。 前面四条调用指令的分派逻辑都固化在Java虚拟机内部 用户无法改变 而invokedynamic指令的分派逻辑是由用户所设定的引导方法决定的异常处理指令
athrow
处理异常是由异常表来完成的而非字节码指令。
同步指令
Java虚拟机可以支持方法级的同步和方法内部一段指令序列的同步 这两种同步结构都是使用管程Monitor 更常见的是直接将它称为“锁” 来实现的。
方法级的同步是隐式的 无须通过字节码指令来控制 它实现在方法调用和返回操作之中。 虚拟机可以从方法常量池中的方法表结构中的ACC_SYNCHRONIZED访问标志得知一个方法是否被声明为同步方法。 当方法调用时 调用指令将会检查方法的ACC_SYNCHRONIZED访问标志是否被设置 如果设置了 执行线程就要求先成功持有管程 然后才能执行方法 最后当方法完成无论是正常完成还是非正常完成 时释放管程。 在方法执行期间 执行线程持有了管程 其他任何线程都无法再获取到同一个管程。 如果一个同步方法执行期间抛出了异常 并且在方法内部无法处理此异常 那这个同步方法所持有的管程将在异常抛到同步方法边界之外时自动释放。同步一段指令集序列通常是由Java语言中的synchronized语句块来表示的 Java虚拟机的指令集中monitorenter和monitorexit两条指令来支持synchronized关键字的语义 正确实现synchronized关键字需要Javac编译器与Java虚拟机两者共同协作支持 .
下篇文章针对这点做实例分析。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/914356.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!