Java 虚拟机指令(操作码)集
最近在研究 Java 虚拟机字节码。在 《Java虚拟机规范》 看到一个整理完整的 Java 虚拟机指令集(也叫操作码)列表。转载过来,方便查阅。
关于 Java 虚拟机指令(操作码),准备写一个“探秘”系列:
Java 虚拟机操作码探秘:常量指令 — 重点介绍一下关于“常量”指令。
分类 | 操作码 | 助记符 | 指令含义 | |
---|---|---|---|---|
常量 | 0 |
| 什么都不做 | |
1 |
| 将 null 推送至栈顶 | ||
2 |
| 将 int 类型 -1 推送至栈顶 | ||
3 |
| 将 int 类型 0 推送至栈顶 | ||
4 |
| 将 int 类型 1 推送至栈顶 | ||
5 |
| 将 int 类型 2 推送至栈顶 | ||
6 |
| 将 int 类型 3 推送至栈顶 | ||
7 |
| 将 int 类型 4 推送至栈顶 | ||
8 |
| 将 int 类型 5 推送至栈顶 | ||
9 |
| 将 long 类型 0 推送至栈顶 | ||
10 |
| 将 long 类型 1 推送至栈顶 | ||
11 |
| 将 float 类型 0 推送至栈顶 | ||
12 |
| 将 float 类型 1 推送至栈顶 | ||
13 |
| 将 float 类型 2 推送至栈顶 | ||
14 |
| 将 double 类型 0 推送至栈顶 | ||
15 |
| 将 double 类型 1 推送至栈顶 | ||
16 |
| 将单字节的常量值(-128 ~ 127)推送至栈顶 | ||
17 |
| 将一个短整类型常量值(-32,768 ~ 32,767)推送栈顶 | ||
18 |
| 将 int、 float 或 String 类型常量值从常量池中推送至栈顶 | ||
19 |
| 将int、 float 或 String 类型常量值从常量池中推送栈顶(宽索引) | ||
20 |
| 将 long 或 double 类型常量值从常量池中推送至栈(宽索引) | ||
加载 | 21 |
| 将指定的 int 类型本地变量推送至栈顶 | |
22 |
| 将指定的 long 类型本地变量推送至栈顶 | ||
23 |
| 将指定的 float 类型本地变量推送至栈顶 | ||
24 |
| 将指定的 double 类型本地变量推送至栈顶 | ||
25 |
| 将指定的引用类型本地变量推送至栈顶 | ||
26 |
| 将第 1 个 int 类型本地变量推送至栈顶 | ||
27 |
| 将第 2 个 int 类型本地变量推送至栈顶 | ||
28 |
| 将第 3 个 int 类型本地变量推送至栈顶 | ||
29 |
| 将第 4 个 int 类型本地变量推送至栈顶 | ||
30 |
| 将第 1 个 long 类型本地变量推送至栈顶 | ||
31 |
| 将第 2 个 long 类型本地变量推送至栈顶 | ||
32 |
| 将第 3 个 long 类型本地变量推送至栈顶 | ||
33 |
| 将第 4 个 long 类型本地变量推送至栈顶 | ||
34 |
| 将第 1 个 float 类型本地变量推送至栈顶 | ||
35 |
| 将第 2 个 float 类型本地变量推送至栈顶 | ||
36 |
| 将第 3 个 float 类型本地变量推送至栈顶 | ||
37 |
| 将第 4 个 float 类型本地变量推送至栈顶 | ||
38 |
| 将第 1 个 double 类型本地变量推送至栈顶 | ||
39 |
| 将第 2 个 double 类型本地变量推送至栈顶 | ||
40 |
| 将第 3 个 double 类型本地变量推送至栈顶 | ||
41 |
| 将第 4 个 double 类型本地变量推送至栈顶 | ||
42 |
| 将第 1 个引用类型本地变量推送至栈顶 | ||
43 |
| 将第 2 个引用类型本地变量推送至栈顶 | ||
44 |
| 将第 3 个引用类型本地变量推送至栈顶 | ||
45 |
| 将第 4 个引用类型本地变量推送至栈顶 | ||
46 |
| 将 int 类型数组的指定元素推送至栈顶 | ||
47 |
| 将 long 类型数组的指定元素推送至栈顶 | ||
48 |
| 将 float 类型数组的指定元素推送至栈顶 | ||
49 |
| 将 double 类型数组的指定元素推送至栈顶 | ||
50 |
| 将引用类型数组的指定元素推送至栈顶 | ||
51 |
| 将 boolean 或 byte 类型数组的指定元素推送至栈顶 | ||
52 |
| 将 char 类型数组的指定元素推送至栈顶 | ||
53 |
| 将 short 类型数组的指定元素推送至栈顶 | ||
存储 | 54 |
| 将栈顶 int 类型数值存入指定本地变量 | |
55 |
| 将栈顶 long 类型数值存入指定本地变量 | ||
56 |
| 将栈顶 float 类型数值存入指定本地变量 | ||
57 |
| 将栈顶 double 类型数值存入指定本地变量 | ||
58 |
| 将栈顶引用类型数值存入指定本地变量 | ||
59 |
| 将栈顶 int 类型数值存入第 1 个本地变量 | ||
60 |
| 将栈顶 int 类型数值存入第 2 个本地变量 | ||
61 |
| 将栈顶 int 类型数值存入第 3 个本地变量 | ||
62 |
| 将栈顶 int 类型数值存入第 4 个本地变量 | ||
63 |
| 将栈顶 long 类型数值存入第 1 个本地变量 | ||
64 |
| 将栈顶 long 类型数值存入第 2 个本地变量 | ||
65 |
| 将栈顶 long 类型数值存入第 3 个本地变量 | ||
66 |
| 将栈顶 long 类型数值存入第 4 个本地变量 | ||
67 |
| 将栈顶 float 类型数值存入第 1 个本地变量 | ||
68 |
| 将栈顶 float 类型数值存入第 2 个本地变量 | ||
69 |
| 将栈顶 float 类型数值存入第 3 个本地变量 | ||
70 |
| 将栈顶 float 类型数值存入第 4 个本地变量 | ||
71 |
| 将栈顶 double 类型数值存入第 1 个本地变量 | ||
72 |
| 将栈顶 double 类型数值存入第 2 个本地变量 | ||
73 |
| 将栈顶 double 类型数值存入第 3 个本地变量 | ||
74 |
| 将栈顶 double 类型数值存入第 4 个本地变量 | ||
75 |
| 将栈顶引用类型数值存入第 1 个本地变量 | ||
76 |
| 将栈顶引用类型数值存入第 2 个本地变量 | ||
77 |
| 将栈顶引用类型数值存入第 3 个本地变量 | ||
78 |
| 将栈顶引用类型数值存入第 4 个本地变量 | ||
79 |
| 将栈顶 int 类型数值存入指定数组的指定索引位置 | ||
80 |
| 将栈顶 long 类型数值存入指定数组的指定索引位置 | ||
81 |
| 将栈顶 float 类型数值存入指定数组的指定索引位置 | ||
82 |
| 将栈顶 double 类型数值存入指定数组的指定索引位置 | ||
83 |
| 将栈顶引用类型数值存入指定数组的指定索引位置 | ||
84 |
| 将栈顶 boolean 或 byte 类型数值存入指定数组的指定索引位置 | ||
85 |
| 将栈顶 char 类型数值存入指定数组的指定索引位置 | ||
86 |
| 将栈顶 short 类型数值存入指定数组的指定索引位置 | ||
栈 | 87 |
| 将栈顶数值弹出(数值不能是 long 或 double 类型的) | |
88 |
| 将栈顶的一个 long 或 double 类型的数值或两个其他类型的数值弹出 | ||
89 |
| 复制栈顶数值并将复制值压入栈顶 | ||
90 |
| 复制栈顶值并将其插入栈顶那两个值的下面 | ||
91 |
| 复制栈顶值并将其插入栈顶那两个或三个值的下面 | ||
92 |
| 复制栈顶的一个 long 或 double 类型的值,或两个其他类型的值,并将其压入栈顶 | ||
93 |
| 复制栈顶的一个或两个值,并将其插入栈顶那两个或三个值的下面 | ||
94 |
| 复制栈顶的一个或两个值,并将其插入栈顶那两个、三个或四个值的下面 | ||
95 |
| 将栈顶的两个数值互换(数值不能是 long 或 double 类型的) | ||
数学 | 96 |
| 将栈顶两 int 类型数值相加并将结果压入栈顶 | |
97 |
| 将栈顶两 1ong 类型数值相加并将结果压入栈顶 | ||
98 |
| 将栈顶两 float 类型数值相加并将结果压入栈顶 | ||
99 |
| 将栈顶两 double 类型数值相加并将结果压入栈顶 | ||
100 |
| 将栈顶两 int 类型数值相减并将结果压入栈顶 | ||
101 |
| 将栈顶两 long 类型数值相减并将结果压入栈顶 | ||
102 |
| 将栈顶两 float 类型数值相减并将结果压入栈顶 | ||
103 |
| 将栈顶两 double 类型数值相减并将结果压入栈顶 | ||
104 |
| 将栈顶两 int 类型数值相乘并将结果压入栈顶 | ||
105 |
| 将栈顶两 long 类型数值相乘并将结果压入栈顶 | ||
106 |
| 将栈顶两 float 类型数值相乘并将结果压入栈顶 | ||
107 |
| 将栈顶两 double 类型数值相乘并将结果压入栈顶 | ||
108 |
| 将栈顶两 int 类型数值相除并将结果压入栈顶 | ||
109 |
| 将栈顶两 long 类型数值相除并将结果压入栈顶 | ||
110 |
| 将栈顶两 float 类型数值相除并将结果压入栈顶 | ||
111 |
| 将栈顶两 double 类型数值相除并将结果压入栈顶 | ||
112 |
| 将栈顶两 int 类型数值作取模运算并将结果压入栈顶 | ||
113 |
| 将栈顶两 long 类型数值作取模运算并将结果压入栈顶 | ||
114 |
| 将栈顶两 float 类型数值作取模运算并将结果压入栈顶 | ||
115 |
| 将栈顶两 double 类型数值作取模运算并将结果压入栈顶 | ||
116 |
| 将栈顶 int 类型数值取负并将结果压入栈顶 | ||
117 |
| 将栈顶 long 类型数值取负并将结果压入栈顶 | ||
118 |
| 将栈顶 float 类型数值取负并将结果压入栈顶 | ||
119 |
| 将栈顶 double 类型数值取负并将结果压入栈顶 | ||
120 |
| 将 int 类型数值左移位指定位数并将结果压入栈顶 | ||
121 |
| 将 long 类型数值左移位指定位数并将结果压入栈顶 | ||
122 |
| 将 int 类型数值(有符号)右移位指定位数并将结果压入栈顶 | ||
123 |
| 将 long 类型数值(有符号)右移位指定位数并将结果压入栈顶 | ||
124 | 0x7c | 将 int 类型数值(无符号)右移位指定位数并将结果压入栈顶 | ||
125 |
| 将 long 类型数值(无符号)右移位指定位数并将结果压入栈顶 | ||
126 |
| 将栈顶两 int 类型数值作“按位与”并将结果压入栈顶 | ||
127 |
| 将栈顶两 long 类型数值作“按位与”并将结果压入栈顶 | ||
128 |
| 将栈顶两 int 类型数值作“按位或”并将结果压入栈顶 | ||
129 | 0x81 | 将栈顶两 long 类型数值作“按位或”并将结果压入栈顶 | ||
130 |
| 将栈顶两 int 类型数值作“按位异或”并将结果压入栈顶 | ||
131 |
| 将栈顶两 long 类型数值作“按位异或”并将结果压入栈顶 | ||
132 |
| 将指定 int 类型变量增加指定值( | ||
转换 | 133 |
| 将栈顶 int 类型数值强制转换成 long 类型数值并将结果压入栈顶 | |
134 |
| 将栈顶 int 类型数值强制转换成 float 类型数值并将结果压入栈顶 | ||
135 |
| 将栈顶 int 类型数值强制转换成 double 类型数值并将结果压入栈顶 | ||
136 |
| 将栈顶 long 类型数值强制转换成 int 类型数值并将结果压入栈顶 | ||
137 |
| 将栈顶 long 类型数值强制转换成 float 类型数值并将结果压入栈顶 | ||
138 |
| 将栈顶 long 类型数值强制转换成 double 类型数值并将结果压入栈顶 | ||
139 |
| 将栈顶 float 类型数值强制转换成 int 类型数值并将结果压入栈顶 | ||
140 |
| 将栈顶 float 类型数值强制转换成 long 类型数值并将结果压入栈顶 | ||
141 |
| 将栈顶 float 类型数值强制转换成 double 类型数值并将结果压入栈顶 | ||
142 |
| 将栈顶 double 类型数值强制转换成 int 类型数值并将结果压入栈顶 | ||
143 |
| 将栈顶 double 类型数值强制转换成 long 类型数值并将结果压入栈顶 | ||
144 |
| 将栈顶 double 类型数值强制转换成 float 类型数值并将结果压入栈顶 | ||
145 |
| 将栈顶 int 类型数值强制转换成 byte 类型数值并将结果压入栈顶 | ||
146 |
| 将栈顶 int 类型数值强制转换成 char 类型数值并将结果压入栈顶 | ||
147 |
| 将栈顶 int 类型数值强制转换成 short 类型数值并将结果压入栈顶 | ||
比较 | 148 |
| 比较栈顶两 long 类型数值大小,并将结果(1,0,-1)压入栈顶 | |
149 |
| 比较栈顶两 float 类型数值大小,并将结果(1,0,-1)压入栈顶;当其中一个数值为“NaN”时,将 -1 压入栈顶 | ||
150 |
| 比较栈顶两 float 类型数值大小,并将结果(1,0,-1)压入栈顶;当其中一个数值为“NaN”时,将1压入栈顶 | ||
151 |
| 比较栈顶两 double 类型数值大小,并将结果(1,0,-1)压入栈顶;当其中一个数值为“NaN”时,将-1压入栈顶 | ||
152 |
| 比较栈顶两 double 类型数值大小,并将结果(1,0,-1)压入栈顶;当其中一个数值为“NaN”时,将1压入栈顶 | ||
153 |
| 当栈顶 int 类型数值等于 0 时跳转 | ||
154 |
| 当栈顶 int 类型数值不等于 0 时跳转 | ||
155 |
| 当栈顶 int 类型数值小于 0 时跳转 | ||
156 |
| 当栈顶 int 类型数值大于等于 0 时跳转 | ||
157 |
| 当栈顶 int 类型数值大于 0 时跳转 | ||
158 |
| 当栈顶 int 类型数值小于等于 0 时跳转 | ||
159 |
| 比较栈顶两 int 类型数值大小,当前者等于后者时跳转 | ||
160 |
| 比较栈顶两 int 类型数值大小,当前者不等于后者时跳转 | ||
161 |
| 比较栈顶两 int 类型数值大小,当前者小于后者时跳转 | ||
162 |
| 比较栈顶两 int 类型数值大小,当前者大于等于后者时跳转 | ||
163 |
| 比较栈顶两 int 类型数值大小,当前者大于后者时跳转 | ||
164 |
| 比较栈顶两 int 类型数值大小,当前者小于等于后者时跳转 | ||
165 |
| 比较栈顶两引用类型数值,当结果相等时跳转 | ||
166 |
| 比较栈顶两引用类型数值,当结果不相等时跳转 | ||
控制 | 167 |
| 无条件跳转 | |
168 |
| 跳转至指定 16 位 offset 位置,并将 jsr 下一条指令地址压入栈顶 | ||
169 |
| 返回至由指定的局部变量所给出的指令位置(一般与 jsr、jsr_w 联合使用) | ||
170 |
| 用于 switch 条件跳转,case 值连续(变长指令) | ||
171 |
| 用于 switch 条件跳转,case 值不连续(变长指令) | ||
172 |
| 从当前方法返回 int | ||
173 |
| 从当前方法返回 long | ||
174 |
| 从当前方法返回 float | ||
175 |
| 从当前方法返回 double | ||
176 |
| 从当前方法返回对象引用 | ||
177 |
| 从当前方法返回void | ||
引用 | 178 |
| 获取指定类的静态字段,并将其值压入栈顶 | |
179 |
| 为指定类的静态字段赋值 | ||
180 |
| 获取指定类的实例字段,并将其值压入栈顶 | ||
181 |
| 为指定类的实例字段赋值 | ||
182 |
| 调用实例方法 | ||
183 |
| 调用父类方法、实例初始化方法、私有方法 | ||
184 |
| 调用静态方法 | ||
185 |
| 调用接口方法 | ||
186 |
| 调用动态链接方法 | ||
187 |
| 创建一个对象,并将其引用值压入栈顶 | ||
188 |
| 创建一个指定原始类型(如int、float 、char等)的数组,并将其引用值压入栈顶 | ||
189 |
| 创建一个引用型(如类、接口、数组)的数组,并将其引用值压入栈顶 | ||
190 |
| 获得数组的长度值并压入栈顶 | ||
191 |
| 将栈顶的异常抛出 | ||
192 | 0xcO | 检验类型转换,检验未通过将抛出 ClassCastException | ||
193 | 0xc1 | 检验对象是否是指定类的实例。如果是,就将 1 压入栈顶,否则将 0 压入栈顶 | ||
194 |
| 获得对象的锁,用于实现同步块 | ||
195 |
| 释放对象的锁,用于实现同步块 | ||
扩展 | 196 |
| 扩展本地变量索引的宽度 | |
197 |
| 创建指定类型和指定维度的多维数组(执行该指令时,操作栈中必须包含各维度的长度值),并将其引用值压入栈顶 | ||
198 |
| 为nu11时跳转 | ||
199 |
| 不为nu11时跳转 | ||
200 |
| 无条件跳转(宽索引) | ||
201 |
| 跳转至指定 32 位 offset 位置,并将 jsr_w 下一条指令地址压入栈顶 | ||
保留指令 | 202 |
| breakpoint | 调试时的断点标记 |
254 |
| impdep1 | 为特定软件面预留的语言后门 | |
255 |
| impdep2 | 为特定硬件面预留的语言后门 |