Java栈和局部变量操作(二)
2通用栈操作
操作码 |
操作数 |
说明 |
---|---|---|
nop |
(无) |
不做任何操作 |
pop |
(无) |
从操作数栈弹出栈顶部的一个字 |
pop2 |
(无) |
从操作数栈弹出最顶端的两个字 |
swap |
(无) |
交换栈顶部的两个字 |
dup |
(无) |
复制栈顶部的一个字 |
dup2 |
(无) |
复制栈顶部的两个字 |
dup_x1 |
(无) |
复制栈顶部的一个字,并将复制内容及原来弹出的两个字长的内容压入栈 |
dup_x2 |
(无) |
复制栈顶部的一个字,并将复制内容及原来弹出的三个字长的内容压入栈 |
dup2_x1 |
(无) |
复制栈顶部的两个字,并将复制内容及原来弹出的三个字长的内容压入栈 |
dup2_x2 |
(无) |
复制栈顶部的两个字,并将复制内容及原来弹出的四个字长的内容压入栈 |
1,dup:复制栈顶部的一个字长的内容。
栈:
前:......,word
后:......,word,word
2,dup_x1:复制栈顶部一个字长的内容,然后将复制内容及原来弹出的两个字长的内容压入栈
栈:
前:......,word2,word1
后:......,word1,word2,word1
3,dup_x2:复制栈顶部一个字长的内容,然后将复制内容及原来弹出的三个字长的内容压入栈
栈:
前:.......,word3,word2,word1
后:.......,word1,word3,word2,word1
4,dup2:复制栈顶部长度为两个字长的内容
栈:
前:......,word2,word1
后:......,word2,word1,word2,word1
5,dup2_x1:复制栈顶部两个字长的内容,然后将复制内容及原来弹出的三个字长的内容压入栈
栈:
前:......,word3,word2,word1
后:.......,word2,word1,word3,word2,word1
6,dup2_x2:复制栈顶部两个字长的内容,然后将复制内容及原来弹出的四个字长的内容压入栈
栈:
前:......,word4,word3,word2,word1
后:.......,word2,word1,word4,word3,word2,word1
7,pop:弹出栈顶端一个字长的内容
栈:
前:......,word
后:.......
8,pop2:弹出栈顶端两个字长的内容
栈:
前:......,word2,word1
后:.......
9,swap:交换栈顶端两个字的内容
栈:
前:......,word2,word1
后:.......,word1,word2
例如如下代码:
public class StackTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String a;
String b;
a = new String("aaa");
b = new String("aaa");
}
}
用javap工具查看其字节码为:
Compiled from "StackTest.java"
public class StackTest extends java.lang.Object{
public StackTest();
Code:
0: aload_0
1: invokespecial #8; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: new #16; //class java/lang/String
3: dup
4: ldc #18; //String aaa
6: invokespecial #20; //Method java/lang/String."<init>":(Ljava/lang/String;)V
9: astore_1
10: new #16; //class java/lang/String
13: dup
14: ldc #18; //String aaa
16: invokespecial #20; //Method java/lang/String."<init>":(Ljava/lang/String;)V
19: astore_2
20: return
}
3,把局部变量压入栈
将一个字长的局部变量压入栈
操作码 |
操作数 |
说明 |
---|---|---|
iload |
vindex |
将位置为vindex的int类型的局部变量压入栈 |
iload_0 |
(无) |
将位置为0的int类型的局部变量压入栈 |
iload_1 |
(无) |
将位置为1的int类型的局部变量压入栈 |
iload_2 |
(无) |
将位置为2的int类型的局部变量压入栈 |
iload_3 |
(无) |
将位置为3的int类型的局部变量压入栈 |
fload |
vindex |
将位置为vindex的float类型的局部变量压入栈 |
fload_0 |
(无) |
将位置为0的float类型的局部变量压入栈 |
fload_1 |
(无) |
将位置为1的float类型的局部变量压入栈 |
fload_2 |
(无) |
将位置为2的float类型的局部变量压入栈 |
fload_3 |
(无) |
将位置为3的float类型的局部变量压入栈 |
将两个字长的局部变量压入栈
操作码 |
操作数 |
说明 |
---|---|---|
lload |
vindex |
将位置为vindex和(vindex+1)的long类型的局部变量压入栈 |
lload_0 |
(无) |
将位置为0和1的long类型的局部变量压入栈 |
lload_1 |
(无) |
将位置为1和2的long类型的局部变量压入栈 |
lload_2 |
(无) |
将位置为2和3的long类型的局部变量压入栈 |
lload_3 |
(无) |
将位置为3和4的long类型的局部变量压入栈 |
dload |
vindex |
将位置为vindex和(vindex+1)的double类型的局部变量压入栈 |
dload_0 |
(无) |
将位置为0和1的double类型的局部变量压入栈 |
dload_1 |
(无) |
将位置为1和2的double类型的局部变量压入栈 |
dload_2 |
(无) |
将位置为2和3double类型的局部变量压入栈 |
dload_3 |
(无) |
将位置为3和4double类型的局部变量压入栈 |
将对象引用局部变量压入栈
操作码 |
操作数 |
说明 |
---|---|---|
aload |
vindex |
将位置为vindex的对象引用局部变量压入栈 |
aload_0 |
(无) |
将位置为0的对象引用局部变量压入栈 |
aload_1 |
(无) |
将位置为1的对象引用局部变量压入栈 |
aload_2 |
(无) |
将位置为2的对象引用局部变量压入栈 |
aload_3 |
(无) |
将位置为3的对象引用局部变量压入栈 |
4,弹出栈顶元素,将其赋给局部变量
弹出一个字长的值,将其赋给局部变量
操作码 |
操作数 |
说明 |
---|---|---|
istore |
vindex |
从栈中弹出int类型值,然后将其存到位置为vindex的局部变量中 |
istore_0 |
(无) |
从栈中弹出int类型值,然后将其存到位置为0的局部变量中 |
istore_1 |
(无) |
从栈中弹出int类型值,然后将其存到位置为1的局部变量中 |
istore_2 |
(无) |
从栈中弹出int类型值,然后将其存到位置为2的局部变量中 |
istore_3 |
(无) |
从栈中弹出int类型值,然后将其存到位置为3的局部变量中 |
fstore |
vindex |
从栈中弹出float类型值,然后将其存到位置为vindex的局部变量中 |
fstore_0 |
(无) |
从栈中弹出float类型值,然后将其存到位置为0的局部变量中 |
fstore_1 |
(无) |
从栈中弹出float类型值,然后将其存到位置为1的局部变量中 |
fstore_2 |
(无) |
从栈中弹出float类型值,然后将其存到位置为2的局部变量中 |
fstore_3 |
(无) |
从栈中弹出float类型值,然后将其存到位置为3的局部变量中 |
弹出对象引用,并将其赋值给局部变量
操作码 |
操作数 |
说明 |
---|---|---|
lstore |
vindex |
从栈中弹出long类型值,然后将其存到位置为vindex和(vindex+1)的局部变量中 |
lstore_0 |
(无) |
从栈中弹出long类型值,然后将其存到位置为0和1的局部变量中 |
lstore_1 |
(无) |
从栈中弹出long类型值,然后将其存到位置为1和2的局部变量中 |
lstore_2 |
(无) |
从栈中弹出long类型值,然后将其存到位置为2和3的局部变量中 |
lstore_3 |
(无) |
从栈中弹出long类型值,然后将其存到位置为3和4的局部变量中 |
dstore |
vindex |
从栈中弹出double类型值,然后将其存到位置为vindex和(vindex+1)的局部变量中 |
dstore_0 |
(无) |
从栈中弹出double类型值,然后将其存到位置为0和1的局部变量中 |
dstore_1 |
(无) |
从栈中弹出double类型值,然后将其存到位置为1和2的局部变量中 |
dstore_2 |
(无) |
从栈中弹出double类型值,然后将其存到位置为2和3的局部变量中 |
dstore_3 |
(无) |
从栈中弹出double类型值,然后将其存到位置为3和4的局部变量中 |
操作码 |
操作数 |
说明 |
---|---|---|
astore |
vindex |
从栈中弹出对象引用,然后将其存到位置为vindex的局部变量中 |
astore_0 |
(无) |
从栈中弹出对象引用,然后将其存到位置为0的局部变量中 |
astore_1 |
(无) |
从栈中弹出对象引用,然后将其存到位置为1的局部变量中 |
astore_2 |
(无) |
从栈中弹出对象引用,然后将其存到位置为2的局部变量中 |
astore_3 |
(无) |
从栈中弹出对象引用,然后将其存到位置为3的局部变量中 |
5,wide指令
无符号8位局部变量索引,把方法中局部变量数的限制在256以下。一条单独的wide指令可以将8位的索引再扩展8位,就可以把局部变量数的限制扩展到65536.
操作码 |
操作数 |
说明 |
---|---|---|
wide |
iload,index |
从局部变量位置为index的地方取出int类型值,并将其压入栈 |
wide |
lload ,index |
从局部变量位置为index的地方取出long类型值,并将其压入栈 |
wide |
fload,index |
从局部变量位置为index的地方取出float类型值,并将其压入栈 |
wide |
dload,index |
从局部变量位置为index的地方取出double类型值,并将其压入栈 |
wide |
aload,index |
从局部变量位置为index的地方取出对象引用,并将其压入栈 |
wide |
istore,index |
从栈中弹出int类型值,将其存入位置为index的局部变量中 |
wide |
lstore,index |
从栈中弹出long类型值,将其存入位置为index的局部变量中 |
wide |
fstore,index |
从栈中弹出float类型值,将其存入位置为index的局部变量中 |
wide |
dstore,index |
从栈中弹出double类型值,将其存入位置为index的局部变量中 |
wide |
astore,index |
从栈中弹出对象引用,将其存入位置为index的局部变量中 |
跳转指令并不允许直接跳转到被wide指令修改过的操作码。
posted on 2011-04-03 10:23 chenqiangjsj 阅读(5894) 评论(0) 编辑 收藏 举报