Java字节码指令

1. 简介

Java虚拟机的指令由一个字节长度的、代表着某种特定操作含义的数字(称为操作码)以及跟随其后的零至多个代表此操作所需参数(称为操作数)而构成。

由于Java虚拟机采用面向操作数栈而不是寄存器的架构,所以大多数的指令都不包含操作数,只有一个操作码。

Java虚拟机操作码的长度为一个字节(即0~255),这意味着指令集的操作码总数不可能超过256条。

2. 字节码和数据类型

在Java虚拟机的指令集中,大多数的指令都包含了其操作所对应的数据类型信息。例如,iload指令用于从局部变量中加载int型的数据到操作数栈中,而fload指令加载的则是float类型的数据。

大部分与数据类型相关的字节码指令,它们的操作码助记符都有特殊的字符来表明专门为哪种数据类型服务:i代表对int类型的数据操作,l代表long,s代表short,b代表byte,c代表char,f代表float,d代表double,a代表reference。也有一些指令的助记符中没有明确地指明操作类型的字母,如arraylength指令。

如果每一种与数据类型相关的指令都支持Java虚拟机所有运行时数据类型的话,那指令的数量就会超出一个字节所能标示的数量范围了。因此,Java虚拟机的指令集对于特定的操作只提供了有限的类型相关指令去支持它,换句话说,指令集将会故意被设计成非完全独立的,有一些单独的指令可以在必要的时候用来将一些不支持的类型转换为可被支持的类型。

3. 字节码分类介绍

3.1 加载和存储指令

加载和存储指令用于将数据在栈帧中的局部变量表和操作数栈之间来回传输。

  • 将一个局部变量加载到操作栈:iload,iload_<n>
  • 将一个数值从操作数栈存储到局部变量表:istore,istore_<n>
  • 将一个常量加载到操作数栈:bipush
  • 扩充局部变量表的访问索引的指令:wide 

其中iload_<n>代表了一组指令,代表了iload_0,iload_1,iload_3这几条指令。这几组指令都是某个带有一个操作数的通用指令的特殊形式,对于这若干组特殊指令来说,他们省略了显式的操作数,不需要进行取操作数的动作。实际上操作数就隐含在指令中。例如,iload_0的语义与操作数为0时的iload指令语义完全一致。

猜你喜欢

转载自www.cnblogs.com/lujiango/p/9088951.html