6.4.2 加载和存储指令

加载和存储指令用于将数据在栈帧中的局部变量表和操作数栈(见第2章关于内存区域的介绍)之间来回传输,这类指令包括如下内容。

将一个局部变量加载到操作栈:iload、iload<n>、lload、lload<n>、fload、fload<n>、dload、dload<n>、aload、aload_<n>。

将一个数值从操作数栈存储到局部变量表:istore、istore<n>、lstore、lstore<n>、fstore、fstore<n>、dstore、dstore<n>、astore、astore_<n>。

将一个常量加载到操作数栈:bipush、sipush、ldc、ldcw、ldc2_w、aconst_null、iconst_m1、iconst<i>、lconst<l>、fconst<f>、dconst_<d>。

扩充局部变量表的访问索引的指令:wide。

存储数据的操作数栈和局部变量表主要就是由加载和存储指令进行操作,除此之外,还有少量指令,如访问对象的字段或数组元素的指令也会向操作数栈传输数据。

上面所列举的指令助记符中,有一部分是以尖括号结尾的(例如iload<n>),这些指令助记符实际上是代表了一组指令(例如iload<n>,它代表了iload_0、iload_1、iload_2和iload_3这几条指令)。这几组指令都是某个带有一个操作数的通用指令(例如iload)的特殊形式,对于这若干组特殊指令来说,它们省略掉了显式的操作数,不需要进行取操作数的动作,实际上操作数就隐含在指令中。除了这点之外,它们的语义与原生的通用指令完全一致(例如iload_0的语义与操作数为0时的iload指令语义完全一致)。这种指令表示方法在本书以及《Java虚拟机规范》中都是通用的。