`
glutinit
  • 浏览: 47490 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

JVM摘要--指令集介绍01

    博客分类:
  • JVM
阅读更多
    一个JVM的指令包含了1个字节的操作码,该操作码用来表示要操作的动作,然后是0个或多个表示操作码的操作对象:参数或者其他数据。许多指令都没有操作数,而只有一个操作码。
    不考虑异常的损耗,JVM解释器的内循环是很有效率的:
do{
atomically calculate pc and fetch opcode at pc;
                If (operands) fetch operands;
                execute the action for the opcode;
        }while(there is more to do)

     操作数的数量和大小由操作码决定。比如,如果一个16-bit大小的索引要存放在局域变量中,则要存放在2个字节中,记为byte1和byte2,所以这样存放的变量,其所表达的值为(byte1<<8)|byte2。

1.类型和JVM

    大多数JVM中的指令集都要求它们要操作的动作所涉及的类型设定为一种。比如,iLoad指令表示从局部变量中加载的值必须是int类型的。同理,fload也要求加载的值的类型需要时float。这两个指令有相似的应用,但却有不同的操作数。

    大多数带有类型要求的指令,指令的类型可以通过字母明显的看出。比如,i表示针对int的操作,l表示long,s表示short,b表示byte,c表示char,f表示float,d表示double,而a表示reference。而有些命令则没有表示类型的字母,比如arrayLength通常都是针对一个数组的操作。而一些类似goto的命令,则不操作带有类型信息的操作数。

    从下面的表中,可以看出很多含有类型标注的指令。其中大多数的指中,byte,char和short都是空的。并且其中没有看到boolean的相关内容。怎么回事呢?在编译或运行时,编译器会将byte和short的值利用符号扩展变为int的值,然后再加以使用。而boolean和char的值则利用了0填充的方法将其值转换为int。

     同样,从数组中加载boolean,short,byte,和char的值都被JVM在编译或运行期利用符号扩展或0扩展转变成了int类型的值。可以说,boolea,byte,char和short的操作与int的操作用的是一样的指令。
    
    
      2. Load和Store指令

load和store指令是指操作数栈和局部变量区中的值的互相传递,局部变量区(local variables)和操作数栈(operand stack)都属于JVM帧(frame),这些指令包括:

• Load a local variable onto the operand stack: iload, iload_<n>, lload, lload_<n>, fload, fload_<n>, dload, dload_<n>, aload, aload_<n>.
• Store a value from the operand stack into a local variable: istore, istore_<n>,lstore, lstore_<n>, fstore, fstore_<n>, dstore, dstore_<n>, astore, astore_<n>.
• Load a constant onto the operand stack: bipush, sipush, ldc, ldc_w, ldc2_w,aconst_null, iconst_m1, iconst_<i>, lconst_<l>, fconst_<f>, dconst_<d>.
• Gain access to more local variables using a wider index, or to a larger immediate operand: wide.

3.算术指令
    算术指令,一般都是从操作数栈中获得两个操作数,然后这两个数计算得到结果放回到操作数栈中。根据操作数的类型分,有两大类的算术指令,一是操作整数的指令;一是操作浮点类型的指令。没有直接操作byte,short,char或boolean类型的算术指令,它们都被视为int来进行操作。整数和浮点类型的操作指令的区别还体现在对“溢出”和“被0除”的行为上。算术指令包括:
    • Add: iadd, ladd, fadd, dadd.
    • Subtract: isub, lsub, fsub, dsub.
    • Multiply: imul, lmul, fmul, dmul.
    • Divide: idiv, ldiv, fdiv, ddiv.
    • Remainder: irem, lrem, frem, drem.
    • Negate: ineg, lneg, fneg, dneg.
    • Shift: ishl, ishr, iushr, lshl, lshr, lushr.
    • Bitwise OR: ior, lor.
    • Bitwise AND: iand, land.
    • Bitwise exclusive OR: ixor, lxor.
    • Local variable increment: iinc.
    • Comparison: dcmpg, dcmpl, fcmpg, fcmpl, lcmp.

   JVM不会表示出整数类型的“溢出”。只有当除数为0的时候,针对int的操作才会抛出ArithmeticException,会跑出该异常的指令有:idiv, ldiv, irem,lrem; 针对浮点类型的指令遵循IEEE 754的标准。

4.转型指令

    转换指令允许JVM的数字类型之间进行转型。

   JVM支持一下几种向上转型:
   •int to long, float, or double 指令为 i2l, i2f,i2d
   •long to float or double          指令为l2f,l2d
   •float to double     指令为f2d

     其中,i2l, i2d, f2d这三个转型指令不会发生精度丢失的问题。而i2f, l2f, l2d 这三个转型指令可能会有精度丢失的问题,即它们回让最低有效位的一些值丢失.除去有可能的精度丢失,向上转型不会让JVM抛出Runtime Exception;

以及几种向下转型:

  •int to byte, short, or char 指令为i2b,i2s,i2c
  •long to int         指令为l2i
  •float to int or long         指令为f2i,f2l
  •double to int, long, or float 指令为d2i,d2l,d2f

    显然,向下转型会引起精度丢失,有可能会让数字的正负号发生变化,有可能会让数量发生变化,或者两者都变化。一般来说向下转型要谨慎使用…很多bug都隐藏在向下转型中~

       
分享到:
评论

相关推荐

    The Java Virtual Machine Specification, Java SE 7 Edition

    文档提供了一个指令集摘要,详细介绍了不同类型的指令,如加载/存储指令、算术指令、类型转换指令、对象创建与操作指令、操作数栈管理指令、控制转移指令、方法调用与返回指令以及抛出异常指令等。 10. Special ...

    一种实时Java处理器的指令存取部件设计与实现.pdf

    由于Java虚拟机(JVM)基于堆栈的实现方式,处理器的存储体系结构与传统的RISC(精简指令集计算)处理器有所不同。文章提出了一种针对实时Java处理器的指令预取方案,该方案很好地适应了Java特有的体系结构。 ...

    Java虚拟机规范

    5. 指令集:JVM使用字节码作为中间语言,如`aload_0`表示加载局部变量表的第一个引用类型变量。字节码通过解释器或即时编译器(JIT)转化为机器码执行。 6. 内存管理:Java的内存管理主要包括自动垃圾收集,采用...

    Java虚拟机规范(英文)

    6. 规范的作用:JVM规范作为Java平台的基础性文档,规定了JVM的内部架构、数据类型、指令集、运行时数据区、垃圾收集机制等核心内容,是Java开发者和虚拟机实现者必须遵循的标准。 综合以上内容,我们可以看到...

    Java高级面试题附答案汇总(2021年Java面试题及答案大全)

    本资源摘要信息涵盖了Java高级面试题附答案汇总(2021年Java面试题及答案大全),涵盖了多个知识点,包括Java高级面试题、序列化、多线程同步、GC算法、集合类型、JDK自带的监控和性能分析工具等。 1. ...

    Java期末考试题及答案.pdf

    JVM对下列各项做出了定义:指令集、寄存器、类文件格式、栈、垃圾收集堆、存储区。 Java虚拟机的功能包括: * 通过ClassLoader寻找和装载Class文件 * 解释字节码成为指令并执行,提供Class文件的运行环境 * 进行...

    JavaSE知识点总结.doc

    CPU执行指令,内存用于存储程序运行时的数据,硬盘则用于长期存储数据。程序的运行基于冯·诺依曼体系结构,即计算机通过输入、处理、输出和存储四个步骤执行任务。 #### 2. 不同类型语言的编译与运行 编程语言大致...

    Java Web之高级应用

    类装载器是Java应用程序运行的核心组成部分,它负责加载类到JVM中。在Tomcat中,类装载器有明确的层次结构,每个Web应用程序都有自己的类装载器,以确保类的隔离。在示例中,通过context.xml配置资源,如邮件服务,...

    很强的Java加密解密算法

    算法是解决特定问题的步骤或指令集。在加密和解密领域,常见的算法包括对称加密(如DES、3DES、AES)、非对称加密(如RSA、ECC)、哈希函数(如MD5、SHA-1、SHA-256)以及消息认证码(MAC)等。这些算法都有其独特...

Global site tag (gtag.js) - Google Analytics