当前位置: 首页 > article >正文

加载与存储指令及算数指令

我的后端学习大纲

JVM学习大纲
------------------------------------------------------------------------------------------------------------------------------]

2.加载与存储指令:

在这里插入图片描述
在这里插入图片描述

iload_0占1个字节。iload 0 占3个字节。
因为操作码数量有限,只有256个,所以只把常用的0-3设置成了操作码。

2.1.复习操作数栈

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2.局部变量压栈指定:

  • 1.局部变量压栈指令将给定的局部变量表中的数据压入操作数栈。
  • 2.这类指令大体可以分为:
> xload_<n>(x为i、1、f、d、a,n为03> 
> xload (x为i、1、f、d、a)
说明:在这里,x的取值表示数据类型。
指令xload_n表示将第n个局部变量压入操作数栈,比如iload_1、fload_0、aload_0等指令。其中aload_n表示将一个对象引用压栈。
指令xload通过指定参数的形式,把局部变量压入操作数栈,当使用这个命令时,表示局部变量的数量可能超过了4个,比如指令iload、fload等。

在这里插入图片描述
在这里插入图片描述

2.3.常量入栈指令:

常量入栈指令的功能是将常数压入操作数栈,根据数据类型和入栈内容的不同,又可以分为const系列、push系列和ldc指令。
指令const系列:用于对特定的常量入栈,入栈的常量隐含在指令本身里。指令有: iconst_ (i从-1到5)、lconst_(1从0到1)、fconst_(f从0到2)、dconst_(d从0到1)、aconst_null。
比如,
iconst_m1将-1压入操作数栈;iconst_x (x为0到5)将x压入栈:
lconst_0、lconst_1分别将长整数9和1压入栈;
fconstl 0、fconst_1、fconst_2分别将浮点数0、1、2压入栈;dconst_0和dconst_1分别将double型o和1压入栈。
aconst_null将null压入操作数栈;
从指令的命名上不难找出规律,指令助记符的第一个字符总是喜欢表示数据类型,i表示整数,1表示长整数,f表示浮点数,d表示双精度浮点,习惯上用a表示对象引用。如果指令隐含操作的参数,会以下划线形式给出。
在这里插入图片描述
指令push系列:主要包括bipush和sipush。它们的区别在于接收数据类型的不同,bipush接收8位整数作为参数,sipush接收16位整数,它们都将参数压入栈。
指令ldc系列:如果以上指令都不能满足需求,那么可以使用万能的ldc指令,它可以接收一个8位的参数,该参数指向常量池中的int、float或者String的索引,将指定的内容压入堆栈。

类似的还有ldc_w,它接收两个8位参数,能支持的索引范围大于ldc。
如果要压入的元素是long或者double类型的,0使用ldc2_w指令,使用方式都是类似的。

在这里插入图片描述

在这里插入图片描述

2.4.出栈装入局部变量表指令:

出栈装入局部变量表指令用于将操作数栈中栈顶元素弹出后,装入局部变量表的指定位置,用于给局部变量赋值。

这类指令主要以store的形式存在,比如xstore (x为i、l、f、d、a)、 xstore_n (x 为i、1、f、d、a, n为0至3)
其中,指令istore_n将从操作数栈中弹出一个整数,并把它赋值给局部变量索引n位置。
指令xstore由于没有隐含参数信息,故需要提供一个byte类型的参数类指定目标局部变量表的位置。
说明:
一般说来,类似像store这样的命令需要带一个参数,用来指明将弹出的元素放在局部变量表的第几个位置。但是,为了尽可能压缩指令大小,使用专门的istore_1指令表示将弹出的元素放置在局部变量表第1个位置。类似的还有
istore_0、istore_2、istore_3,它们分别表示从操作数栈顶弹出一个元素,存放在局部变量表第0、2、3个位置。
由于局部变量表前几个位置总是非常常用,因此这种做法虽然增加了指令数量,但是可以大大压缩生成的字节码的体积。如果局部变量表很大,需要存储的槽位大于3,那么可以使用istore指令,外加一个参数,用来表示需要存放的槽位位置。
在这里插入图片描述


3.算数指令:

1)作用:
算术指令用于对两个操作数栈上的值进行某种特定运算,并把结果重新压入操作数栈
2)分类:
大体上算术指令可以分为两种:对整型数据进行运算的指令与对浮点类型数据进行运算的指令。
3)byte、short、char和boolean类型说明
在每一大类中,都有针对Java虚拟机具体数据类型的专用算术指令。但没有直接支持byte、short、char和boolean类型的算术指令,对于这些数据的运算,都使用int类型的指令来处理。此外,在处理boolean、byte、short和char类型的数组时,也会转换为使用对应的int类型的字节码指令来处理。

在这里插入图片描述
4)运算时的溢出
数据运算可能会导致溢出,例如两个很大的正整数相加,结果可能是一个负数。其实Java虚拟机规范并无明确规定过整
型数据溢出的具体结果,仅规定了在处理整型数据时,只有除法指令以及求余指令中当出现除数为o时会导致虚拟机抛出异常ArithmeticException。
5)运算模式
向最接近数舍入模式:JVM要求在进仃浮点数T昇的,所有色界结木培近览代牛件择最低有效位为零的;
舍入为可被表示的最接近的精确值,如果有两种可表示的形式与该值一样接近,将优先选择最低有效位为零的;
向零舍入模式:将浮点数转换为整数时,采用该模式,该模式将在目标数值类型中选择一个最接近但是不大于原值
的数字作为最精确的舍入结果;
6)NaN值使用
当一个操作产生溢出时,将会使用有符号的无穷大表示,如果某个操作结果没有明确的数学定义的话,将会使用NaN值来表示。而且所有使用NaN值作为操作数的算术操作,结果都会返回 NaN;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

i++与++i的问题

对于不涉及赋值操作的i++和++i并无区别,字节码一模一样
在这里插入图片描述
在这里插入图片描述
验证java基础所学的++在前,先++后赋值;++在后,先赋值,后++。

根据字节码理解
先把10压入操作数栈,然后把10放入局部变量表1的位置,然后把局部变量表1的位置的元素加载到操作数栈,然后对局部变量表1的位置的元素加一,然后把操作数栈中的元素保存到局部变量表2的位置。

先把20压入操作数栈,然后把20放入局部变量表3的位置,然后对局部变量表3的位置的元素加一,然后把局部变量表3的位置的元素加载到操作数栈,然后把操作数栈中的元素保存到局部变量表4的位置。
在这里插入图片描述
为啥打印出来是10?局部变量表中变为了11,但随后又被覆盖了成了10。

比较指令

在这里插入图片描述



http://www.kler.cn/a/389506.html

相关文章:

  • 大模型 | AI驱动的数据分析:利用自然语言实现数据查询到可视化呈现
  • iOS UIScrollView的一个特性
  • SDL2:arm64下编译使用 -- SDL2多媒体库使用音频实例
  • Swift 专题二 语法速查
  • 学习记录之原型,原型链
  • 详解构造函数和析构函数
  • HarmonyOS Next 实战卡片开发 01
  • Android CCodec Codec2 (二十)C2Buffer与Codec2Buffer
  • 深度学习中的 Dropout:原理、公式与实现解析
  • [Linux] 共享内存
  • 使用 IDEA 创建 Java 项目(二)
  • Hive:UDTF 函数
  • 优化时钟网络之时钟偏移
  • leetcode01 --- 环形链表判定
  • 优选算法合集————双指针(专题一)
  • DAF-FM DA与NO反应后,生成的产物能够发出强烈的绿色荧光,254109-22-3
  • Tomcat(10) 如何在Tomcat中配置虚拟主机?
  • Rust-Trait 特征编程
  • HarmonyOS Next 并发 taskpool 和 worker
  • 从0开始学PHP面向对象内容之(常用魔术方法)
  • ElasticSearch:使用dsl语句同时查询出最近2小时、最近1天、最近7天、最近30天的数量
  • 使用概率表示和原型学习的有效半监督医学图像分割|文献速递-基于深度学习的病灶分割与数据超分辨率
  • win11电脑无法找到声音输出设备怎么办?查看解决方法
  • gan的所有种类,人工智能 机器学习,gan的所有算法
  • 离线 快速搭建 docker docker-compose k8s 环境
  • 15.UE5等级、经验、血条,魔法恢复和消耗制作