18.3 字节码指令集与解析举例 - 算数指令

本文详细介绍了Java虚拟机(JVM)中的算术指令,包括对整型和浮点类型数据的操作,如加、减、乘、除、求余和取反等。讨论了运算时可能出现的溢出情况,以及JVM如何处理浮点数计算的精度和NaN值。同时,解释了比较指令如dcmpg、dcmpl等在处理数字比较时的规则,特别是面对NaN值时的行为差异。通过具体的代码示例,展示了字节码指令在实际运算过程中的应用。
摘要由CSDN通过智能技术生成

算数指令

  1. 作用:
    算术指令用于对两个操作数栈上的值进行某种特定运算,并把结果重新压入操作数栈。

  2. 分类:
    大体上算术指令可以分为两种:对整型数据进行运算的指令与对浮点类型数据进行运算的指令。

  3. byte、short、char 和boolean类型说明
    在每一大类中,都有针对Java虚拟机具体数据类型的专用算术指令。但没有直接支持byte、short、 char和boolean类型的算术指令,对于这些数据的运算,都使用int类型的指令来处理。此外,在处理boolean、byte、 short和char类型的数组时,也会转换为使用对应的int类型的字节码指令来处理。

在这里插入图片描述

  1. 运算时的溢出
    数据运算可能会导致溢出,例如两个很大的正整数相加,结果可能是一个负数。其实Java虚拟机规范并无明确规定过整型数据溢出的具体结果,仅规定了在处理整型数据时,只有除法指令以及求余指令中当出现除数为0时会导致虚拟机抛出异常ArithmeticException。
  2. 运算模式
  • 向最接近数舍入模式:JVM要求在进行浮点数计算时,所有的运算结果都必须舍入到适当的精度,非精确结果必须舍入为可被表示的最接近的精确值,如果有两种可表示的形式与该值一样接近,将优先选择最低有效位为零的;
  • 向零舍入模式:将浮点数转换为整数时,采用该模式,该模式将在目标数值类型中选择一个最接近但是不大于原值的数字作为最精确的舍入结果;
  1. NaN值使用
    当一个操作产生溢出时,将会使用有符号的无穷大表示,如果某个操作结果没有明确的数学定义的话,将会使用NaN值来表示。而且所有使用NaN值作为操作数的算术操作,结果都会返回NaN;

在这里插入图片描述

所有算术指令

所有的算术指令包括:
加法指令: iadd、 ladd、fadd、dadd
减法指令: isub、 lsub、fsub、dsub
乘法指令:imul、lmul、 fmul、dmul
除法指令: idiv、ldiv、fdiv、ddiv
求余指令: irem、lrem、frem、drem //remainder:余数
取反指令: ineg、 lneg、 fneg、dneg //negation:取反
自增指令: iinc
位运算指令,又可分为:
位移指令: ishl、 ishr、iushr、 lshl、 lshr、lushr
按位或指令: ior、 lor
按位与指令: iand、 land
按位异或指令: ixor、 lxor
比较指令: dcmpg、dcmpl、fcmpg、fcmpl、lcmp

举例

public static int bar(int i) {
	return ((i + 1) - 2) * 3/4;
}

字节码指令对应的图示:

在这里插入图片描述

一个曾经的案例1

代码:

public void add(){
    byte i = 15;
    int j=8;
    int k=i+j;
}

字节码对应的内存解析:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

一个曾经的案例2

代码:

public static void main(String[] args) {
    int x = 500;
    int y = 100;
    int a= x/y;
    int b= 50;
    System.out.println(a + b);
}

字节码对应的内存解析:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

比较指令的说明

  • 比较指令的作用是比较栈顶两个元素的大小,并将比较结果入栈。
  • 比较指令有:dcmpg、dcmpl、fcmpg、 fcmpl、lcmp。
    • 与前面讲解的指令类似,首字符d表示double类型,f表示float , l表示long。
  • 对于double和float类型的数字,由于NaN的存在,各有两个版本的比较指令。以float为例,有fcmpg和fcmpl两个指令,它们的区别在于在数字比较时,若遇到NaN值,处理结果不同。
  • 指令dcmpl和dcmpg也是类似的,根据其命名可以推测其含义,在此不再赘述。
  • 指令lcmp针对long型整数,由于long型整数没有NaN值, 故无需准备两套指令。

举例:

​ 指令fcmpg和fcmpl都从栈中弹出两个操作数,并将它们做比较,设栈顶的元素为v2,栈顶顺位第2位的元素为v1,若v1=v2,则压入0;若v1>v2则压入1;若v1<v2则压入-1。
两个指令的不同之处在于,如果遇到NaN值,fcmpg会压入1,而fcmpl会压入-1。

数值类型的数据,才可以谈大小!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值