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指令修改過的操作碼。
?
總結
以上是生活随笔為你收集整理的Java栈和局部变量操作(二)的全部內容,希望文章能夠幫你解決所遇到的問題。