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指令修改過的操作碼。
原:http://www.cnblogs.com/chenqiangjsj/archive/2011/04/03/2004231.html