跳轉到內容

Java 程式設計/位元組碼

來自 Wikibooks,開放世界中的開放書籍

Java 位元組碼是 Java 原始碼被編譯成的語言,也是 Java 虛擬機器可以理解的語言。與必須為每種不同型別的計算機專門編譯的編譯語言不同,Java 程式只需要轉換一次為位元組碼,之後它可以在任何存在 Java 虛擬機器的平臺上執行。

位元組碼是 Java 程式的編譯格式。一旦 Java 程式被轉換為位元組碼,它就可以透過網路傳輸並由 Java 虛擬機器 (JVM) 執行。位元組碼檔案通常具有 .class 副檔名。對於 Java 程式設計師來說,通常不需要了解位元組碼,但它可能很有用。



其他語言

[編輯 | 編輯原始碼]

有一些激動人心的新語言正在被建立,它們也編譯成 Java 位元組碼,例如 Groovy

GNAT
GNU Ada 編譯器,能夠將 Ada 編譯成 Java 風格的位元組碼。
ftp://cs.nyu.edu/pub/gnat
JPython
將 Python 編譯成 Java 風格的位元組碼。
http://www.jpython.org/
Kawa
將 Scheme 編譯成 Java 風格的位元組碼。
http://www.gnu.org/software/kawa/


考慮以下 Java 程式碼。

 outer:
 for (int i = 2; i < 1000; i++) {
  for (int j = 2; j < i; j++) {
    if (i % j == 0)
      continue outer;
  }
  System.out.println (i);
 }

Java 編譯器可能會將上面的 Java 程式碼翻譯成以下位元組碼,假設上面的程式碼被放在一個方法中

  Code:
   0:   iconst_2
   1:   istore_1
   2:   iload_1
   3:   sipush  1000
   6:   if_icmpge       44
   9:   iconst_2
   10:  istore_2
   11:  iload_2
   12:  iload_1
   13:  if_icmpge       31
   16:  iload_1
   17:  iload_2
   18:  irem             # remainder
   19:  ifne    25
   22:  goto    38
   25:  iinc    2, 1
   28:  goto    11
   31:  getstatic       #84; //Field java/lang/System.out:Ljava/io/PrintStream;
   34:  iload_1
   35:  invokevirtual   #85; //Method java/io/PrintStream.println:(I)V
   38:  iinc    1, 1
   41:  goto    2
   44:  return

例如,我們可以編寫一個簡單的 Foo.java 原始檔

public class Foo {
  public static void main(final String[] args) {
    System.out.println("This is a simple example of decompilation using javap");
    a();
    b();
  }
	
  public static void a() {
    System.out.println("Now we are calling a function...");
  }

  public static void b() {
    System.out.println("...and now we are calling b");
  }
}

編譯它,然後將 Foo.java 移動到另一個目錄,或者如果你願意,刪除它。我們可以用 javap 和 Foo.class 做什麼?

$javap Foo

產生以下結果

Compiled from "Foo.java"
public class Foo extends java.lang.Object {
    public Foo();
    public static void main(java.lang.String[]);
    public static void a();
    public static void b();
}

如你所見,javac 編譯器不會從 .class 檔案中剝離任何(公共)變數名。因此,函式的名稱、它們的引數和返回值的型別都暴露出來了。(這是為了讓其他類能夠訪問它們所必需的。)

讓我們再做一些,試試

$javap -c Foo
Compiled from "Foo.java"
public class Foo extends java.lang.Object{
public Foo();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:   ldc             #3; //String This is a simple example of decompilation using javap
   5:   invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   8:   invokestatic    #5; //Method a:()V
   11:  invokestatic    #6; //Method b:()V
   14:  return

public static void a();
  Code:
   0:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:   ldc             #7; //String Now we are calling a function...
   5:   invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   8:   return

public static void b();
  Code:
   0:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:   ldc             #8; //String ...and now we are calling b
   5:   invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   8:   return

}

Java 位元組碼

[編輯 | 編輯原始碼]

有關更詳細的描述,請參閱 Oracle 的 Java 虛擬機器規範[1]

運算元棧的操作表示為 [before]→[after],其中 [before] 是執行指令之前棧的狀態,[after] 是執行指令之後棧的狀態。一個棧,其頂部元素為 'b',其下一層元素為 'a',表示為 'a,b'。

助記符 操作碼
(以 十六進位制 表示)
其他位元組
[before]→[after]
描述
A
aaload 32 arrayref, index → value 從陣列中載入引用到堆疊
aastore 53 arrayref, index, value → 將引用儲存到陣列中
aconst_null 01 → null 將一個 null 引用推送到堆疊
aload 19 index → objectref 從本地變數 #index 中載入引用到堆疊
aload_0 2a → objectref 從本地變數 0 中載入引用到堆疊
aload_1 2b → objectref 從本地變數 1 中載入引用到堆疊
aload_2 2c → objectref 從本地變數 2 中載入引用到堆疊
aload_3 2d → objectref 從本地變數 3 中載入引用到堆疊
anewarray bd indexbyte1, indexbyte2 count → arrayref 建立一個新的引用陣列,長度為 count,元件型別由常量池中 index (indexbyte1 << 8 + indexbyte2) 標識的類引用指定
areturn b0 objectref → [empty] 從方法中返回一個引用
arraylength be arrayref → length 獲取陣列的長度
astore 3a index objectref → 將引用儲存到本地變數 #index
astore_0 4b objectref → 將引用儲存到本地變數 0 中
astore_1 4c objectref → 將引用儲存到本地變數 1 中
astore_2 4d objectref → 將引用儲存到本地變數 2 中
astore_3 4e objectref → 將引用儲存到本地變數 3 中
athrow bf objectref → [empty], objectref 丟擲錯誤或異常(注意,其餘堆疊會被清空,只留下對 Throwable 的引用)
B
baload 33 arrayref, index → value 從陣列中載入一個位元組或布林值
bastore 54 arrayref, index, value → 將一個位元組或布林值儲存到陣列中
bipush 10 byte → value 將一個 byte 推送到堆疊作為整數 value
C
caload 34 arrayref, index → value 從陣列中載入一個字元
castore 55 arrayref, index, value → 將一個字元儲存到陣列中
checkcast c0 indexbyte1, indexbyte2 objectref → objectref 檢查一個 objectref 是否是某種型別,該型別的類引用位於常量池中的 index (indexbyte1 << 8 + indexbyte2) 位置
D
d2f 90 value → result 將一個雙精度浮點數轉換為單精度浮點數
d2i 8e value → result 將一個雙精度浮點數轉換為整數
d2l 8f value → result 將一個雙精度浮點數轉換為長整型
dadd 63 value1, value2 → result 將兩個雙精度浮點數相加
daload 31 arrayref, index → value 從陣列中載入一個雙精度浮點數
dastore 52 arrayref, index, value → 將一個雙精度浮點數儲存到陣列中
dcmpg 98 value1, value2 → result 比較兩個雙精度浮點數
dcmpl 97 value1, value2 → result 比較兩個雙精度浮點數
dconst_0 0e → 0.0 將常量 0.0 推送到堆疊
dconst_1 0f → 1.0 將常量 1.0 推送到堆疊
ddiv 6f value1, value2 → result 將兩個雙精度浮點數相除
dload 18 index → value 從本地變數 #index 中載入一個雙精度浮點數 value
dload_0 26 → value 從本地變數 0 中載入一個雙精度浮點數
dload_1 27 → value 從本地變數 1 中載入一個雙精度浮點數
dload_2 28 → value 從本地變數 2 中載入一個雙精度浮點數
dload_3 29 → value 從本地變數 3 中載入一個雙精度浮點數
dmul 6b value1, value2 → result 將兩個雙精度浮點數相乘
dneg 77 value → result 對一個雙精度浮點數取負
drem 73 value1, value2 → result 獲取兩個雙精度浮點數相除的餘數
dreturn af value → [empty] 從方法中返回一個雙精度浮點數
dstore 39 index value → 將一個雙精度浮點數 value 儲存到本地變數 #index
dstore_0 47 value → 將一個雙精度浮點數儲存到本地變數 0 中
dstore_1 48 value → 將一個雙精度浮點數儲存到本地變數 1 中
dstore_2 49 value → 將一個雙精度浮點數儲存到本地變數 2 中
dstore_3 4a value → 將一個雙精度浮點數儲存到本地變數 3 中
dsub 67 value1, value2 → result 從另一個雙精度浮點數中減去一個雙精度浮點數
dup 59 value → value, value 複製堆疊頂部的值
dup_x1 5a value2, value1 → value1, value2, value1 將頂部值的副本插入到距離頂部兩個值的堆疊中
dup_x2 5b value3, value2, value1 → value1, value3, value2, value1 將頂部值的副本插入到距離頂部兩個(如果 value2 是雙精度浮點數或長整型,它也會佔用 value3 的位置)或三個(如果 value2 既不是雙精度浮點數也不是長整型)值的堆疊中
dup2 5c {value2, value1} → {value2, value1}, {value2, value1} 複製堆疊頂部的兩個字(兩個值,如果 value1 既不是雙精度浮點數也不是長整型;一個值,如果 value1 是雙精度浮點數或長整型)
dup2_x1 5d value3, {value2, value1} → {value2, value1}, value3, {value2, value1} 複製兩個字並將它們插入到第三個字的下方(見上文解釋)
dup2_x2 5e {value4, value3}, {value2, value1} → {value2, value1}, {value4, value3}, {value2, value1} 複製兩個字並將它們插入到第四個字的下方
F
f2d 8d value → result 將一個單精度浮點數轉換為雙精度浮點數
f2i 8b value → result 將一個單精度浮點數轉換為整數
f2l 8c value → result 將一個單精度浮點數轉換為長整型
fadd 62 value1, value2 → result 將兩個單精度浮點數相加
faload 30 arrayref, index → value 從陣列中載入一個單精度浮點數
fastore 51 arreyref, index, value → 將一個單精度浮點數儲存到陣列中
fcmpg 96 value1, value2 → result 比較兩個浮點數
fcmpl 95 value1, value2 → result 比較兩個浮點數
fconst_0 0b → 0.0f 0.0f壓入堆疊
fconst_1 0c → 1.0f 1.0f壓入堆疊
fconst_2 0d → 2.0f 2.0f壓入堆疊
fdiv 6e value1, value2 → result 除兩個浮點數
fload 17 index → value 從區域性變數#index載入浮點數value
fload_0 22 → value 從區域性變數0載入浮點數value
fload_1 23 → value 從區域性變數1載入浮點數value
fload_2 24 → value 從區域性變數2載入浮點數value
fload_3 25 → value 從區域性變數3載入浮點數value
fmul 6a value1, value2 → result 乘兩個浮點數
fneg 76 value → result 取浮點數的負值
frem 72 value1, value2 → result 獲取兩個浮點數相除的餘數
freturn ae value → [empty] 從方法返回一個浮點數
fstore 38 index value → 將浮點數value儲存到區域性變數#index
fstore_0 43 value → 將浮點數value儲存到區域性變數0
fstore_1 44 value → 將浮點數value儲存到區域性變數1
fstore_2 45 value → 將浮點數value儲存到區域性變數2
fstore_3 46 value → 將浮點數value儲存到區域性變數3
fsub 66 value1, value2 → result 減去兩個浮點數
G
getfield b4 index1, index2 objectref → value 獲取物件objectref的欄位value,其中欄位由常量池index中的欄位引用標識(index1 << 8 + index2
getstatic b2 index1, index2 → value 獲取類的靜態欄位value,其中欄位由常量池index中的欄位引用標識(index1 << 8 + index2
goto a7 branchbyte1, branchbyte2 [無變化] 轉到branchoffset處的另一個指令(從無符號位元組branchbyte1 << 8 + branchbyte2構造的帶符號短整型)
goto_w c8 branchbyte1, branchbyte2, branchbyte3, branchbyte4 [無變化] 轉到branchoffset處的另一個指令(從無符號位元組branchbyte1 << 24 + branchbyte2 << 16 + branchbyte3 << 8 + branchbyte4構造的帶符號整型)
I
i2b 91 value → result 將int轉換為位元組
i2c 92 value → result 將int轉換為字元
i2d 87 value → result 將int轉換為雙精度浮點數
i2f 86 value → result 將int轉換為單精度浮點數
i2l 85 value → result 將int轉換為長整型
i2s 93 value → result 將int轉換為短整型
iadd 60 value1, value2 → result 將兩個int加在一起
iaload 2e arrayref, index → value 從陣列中載入一個int
iand 7e value1, value2 → result 對兩個整數執行邏輯與運算
iastore 4f arrayref, index, value → 將一個int儲存到陣列中
iconst_m1 02 → -1 將int值-1載入到堆疊中
iconst_0 03 → 0 將int值0載入到堆疊中
iconst_1 04 → 1 將int值1載入到堆疊中
iconst_2 05 → 2 將int值2載入到堆疊中
iconst_3 06 → 3 將int值3載入到堆疊中
iconst_4 07 → 4 將int值4載入到堆疊中
iconst_5 08 → 5 將int值5載入到堆疊中
idiv 6c value1, value2 → result 除兩個整數
if_acmpeq a5 branchbyte1, branchbyte2 value1, value2 → 如果引用相等,則跳轉到branchoffset處的指令(從無符號位元組branchbyte1 << 8 + branchbyte2構造的帶符號短整型)
if_acmpne a6 branchbyte1, branchbyte2 value1, value2 → 如果引用不相等,則跳轉到branchoffset處的指令(從無符號位元組branchbyte1 << 8 + branchbyte2構造的帶符號短整型)
if_icmpeq 9f branchbyte1, branchbyte2 value1, value2 → 如果int相等,則跳轉到branchoffset處的指令(從無符號位元組branchbyte1 << 8 + branchbyte2構造的帶符號短整型)
if_icmpne a0 branchbyte1, branchbyte2 value1, value2 → 如果int不相等,則跳轉到branchoffset處的指令(從無符號位元組branchbyte1 << 8 + branchbyte2構造的帶符號短整型)
if_icmplt a1 branchbyte1, branchbyte2 value1, value2 → 如果value1小於value2,則跳轉到branchoffset處的指令(從無符號位元組branchbyte1 << 8 + branchbyte2構造的帶符號短整型)
if_icmpge a2 branchbyte1, branchbyte2 value1, value2 → 如果value1大於或等於value2,則跳轉到branchoffset處的指令(從無符號位元組branchbyte1 << 8 + branchbyte2構造的帶符號短整型)
if_icmpgt a3 branchbyte1, branchbyte2 value1, value2 → 如果value1大於value2,則跳轉到branchoffset處的指令(從無符號位元組branchbyte1 << 8 + branchbyte2構造的帶符號短整型)
if_icmple a4 branchbyte1, branchbyte2 value1, value2 → 如果value1小於或等於value2,則跳轉到branchoffset處的指令(從無符號位元組branchbyte1 << 8 + branchbyte2構造的帶符號短整型)
ifeq 99 branchbyte1, branchbyte2 value → 如果value為0,則跳轉到branchoffset處的指令(從無符號位元組branchbyte1 << 8 + branchbyte2構造的帶符號短整型)
ifne 9a branchbyte1, branchbyte2 value → 如果value不為0,則跳轉到branchoffset處的指令(從無符號位元組branchbyte1 << 8 + branchbyte2構造的帶符號短整型)
iflt 9b branchbyte1, branchbyte2 value → 如果value小於0,則跳轉到branchoffset處的指令(從無符號位元組branchbyte1 << 8 + branchbyte2構造的帶符號短整型)
ifge 9c branchbyte1, branchbyte2 value → 如果value大於或等於0,則跳轉到branchoffset處的指令(從無符號位元組branchbyte1 << 8 + branchbyte2構造的帶符號短整型)
ifgt 9d branchbyte1, branchbyte2 value → 如果value大於0,則跳轉到branchoffset處的指令(從無符號位元組branchbyte1 << 8 + branchbyte2構造的帶符號短整型)
ifle 9e branchbyte1, branchbyte2 value → 如果value小於或等於0,則跳轉到branchoffset處的指令(從無符號位元組branchbyte1 << 8 + branchbyte2構造的帶符號短整型)
ifnonnull c7 branchbyte1, branchbyte2 value → 如果value不為空,則跳轉到branchoffset處的指令(從無符號位元組branchbyte1 << 8 + branchbyte2構造的帶符號短整型)
ifnull c6 branchbyte1, branchbyte2 value → 如果value為空,則跳轉到branchoffset處的指令(從無符號位元組branchbyte1 << 8 + branchbyte2構造的帶符號短整型)
iinc 84 index, const [無變化] 將區域性變數#index增加帶符號位元組const
iload 15 index → value 從變數#index載入一個intvalue
iload_0 1a → value 從變數0載入一個intvalue
iload_1 1b → value 從變數1載入一個intvalue
iload_2 1c → value 從變數2載入一個intvalue
iload_3 1d → value 從變數3載入一個intvalue
imul 68 value1, value2 → result 乘兩個整數
ineg 74 value → result 取int的負值
instanceof c1 indexbyte1, indexbyte2 objectref → result 確定物件objectref是否為給定型別,由常量池(indexbyte1 << 8 + indexbyte2)中的類引用index標識
invokedynamic ba indexbyte1, indexbyte2 [arg1, arg2, ...] → result 呼叫動態方法並將結果放到堆疊上(可能是void);該方法由常量池(indexbyte1 << 8 | indexbyte2)中的方法引用index標識
invokeinterface b9 indexbyte1, indexbyte2, count, 0 objectref, [arg1, arg2, ...] → 在物件objectref上呼叫介面方法,其中介面方法由常量池(indexbyte1 << 8 + indexbyte2)中的方法引用index標識,count是從堆疊幀中彈出的引數數量,包括呼叫方法的物件,並且必須始終大於或等於1
invokespecial b7 indexbyte1, indexbyte2 objectref, [arg1, arg2, ...] → 呼叫物件objectref上的例項方法,需要特殊處理(例項初始化方法、私有方法或超類方法),其中方法由常量池(indexbyte1 << 8 + indexbyte2)中的方法引用index標識
invokestatic b8 indexbyte1, indexbyte2 [arg1, arg2, ...] → 呼叫靜態方法,其中方法由常量池(indexbyte1 << 8 + indexbyte2)中的方法引用index標識
invokevirtual b6 indexbyte1, indexbyte2 objectref, [arg1, arg2, ...] → 呼叫物件objectref上的虛擬方法,其中方法由常量池(indexbyte1 << 8 + indexbyte2)中的方法引用index標識
ior 80 value1, value2 → result 邏輯int或
irem 70 value1, value2 → result 邏輯int餘數
ireturn ac value → [empty] 從方法返回一個整數
ishl 78 value1, value2 → result int左移
ishr 7a value1, value2 → result int右移
istore 36 index value → 將intvalue儲存到變數#index
istore_0 3b value → 將intvalue儲存到變數0中
istore_1 3c value → 將intvalue儲存到變數1中
istore_2 3d value → 將intvalue儲存到變數2中
istore_3 3e value → 將intvalue儲存到變數3中
isub 64 value1, value2 → result int減法
iushr 7c value1, value2 → result int右移
ixor 82 value1, value2 → result int異或
J
jsr a8 branchbyte1, branchbyte2 → address 跳轉到branchoffset處的子程式並把返回地址放到堆疊上(從無符號位元組branchbyte1 << 8 + branchbyte2構造的帶符號短整型)
jsr_w c9 branchbyte1, branchbyte2, branchbyte3, branchbyte4 → address 跳轉到branchoffset處的子程式並把返回地址放到堆疊上(從無符號位元組branchbyte1 << 24 + branchbyte2 << 16 + branchbyte3 << 8 + branchbyte4構造的帶符號整型)
L
l2d 8a value → result 將長整型轉換為雙精度浮點數
l2f 89 value → result 將長整型轉換為單精度浮點數
l2i 88 value → result 將長整型轉換為整數
ladd 61 value1, value2 → result 將兩個長整型加在一起
laload 2f arrayref, index → value 從陣列中載入一個長整型
land 7f value1, value2 → result 兩個長整型的按位與運算
lastore 50 arrayref, index, value → 將一個長整型儲存到陣列中
lcmp 94 value1, value2 → result 比較兩個長整型值
lconst_0 09 → 0L 將長整型0壓入堆疊
lconst_1 0a → 1L 將長整型1壓入堆疊
ldc 12 index → value 將常量池(字串、int、float 或類型別)中的常量#index壓入堆疊
ldc_w 13 indexbyte1, indexbyte2 → value 將常量池(字串、int、float 或類型別)中的常量#index壓入堆疊(寬index構造為indexbyte1 << 8 + indexbyte2
ldc2_w 14 indexbyte1, indexbyte2 → value 將常量池(雙精度浮點數或長整型)中的常量#index壓入堆疊(寬index構造為indexbyte1 << 8 + indexbyte2
ldiv 6d value1, value2 → result 將兩個長整型數相除
lload 16 index → value 從區域性變數 #index 中載入一個長整型值
lload_0 1e → value 從區域性變數 0 中載入一個長整型值
lload_1 1f → value 從區域性變數 1 中載入一個長整型值
lload_2 20 → value 從區域性變數 2 中載入一個長整型值
lload_3 21 → value 從區域性變數 3 中載入一個長整型值
lmul 69 value1, value2 → result 將兩個長整型數相乘
lneg 75 value → result 對一個長整型數取反
lookupswitch ab <0-3 位元組填充>, defaultbyte1, defaultbyte2, defaultbyte3, defaultbyte4, npairs1, npairs2, npairs3, npairs4, 匹配偏移對... 鍵 → 使用鍵從表中查詢目標地址,並從該地址處的指令開始繼續執行
lor 81 value1, value2 → result 兩個長整型數的按位或運算
lrem 71 value1, value2 → result 兩個長整型數相除的餘數
lreturn ad value → [empty] 返回一個長整型值
lshl 79 value1, value2 → result 將長整型數 value1 按位左移 value2
lshr 7b value1, value2 → result 將長整型數 value1 按位右移 value2
lstore 37 index value → 將長整型數 value 儲存到區域性變數 #index
lstore_0 3f value → 將長整型數 value 儲存到區域性變數 0 中
lstore_1 40 value → 將長整型數 value 儲存到區域性變數 1 中
lstore_2 41 value → 將長整型數 value 儲存到區域性變數 2 中
lstore_3 42 value → 將長整型數 value 儲存到區域性變數 3 中
lsub 65 value1, value2 → result 將兩個長整型數相減
lushr 7d value1, value2 → result 將長整型數 value1 按位右移 value2 位,無符號
lxor 83 value1, value2 → result 兩個長整型數的按位異或運算
M
monitorenter c2 objectref → 進入物件的監視器(“獲取鎖” - 同步化()部分的開始)
monitorexit c3 objectref → 退出物件的監視器(“釋放鎖” - 同步化()部分的結束)
multianewarray c5 indexbyte1, indexbyte2, 維度 count1, [count2,...] → arrayref 建立一個新的陣列,該陣列具有 維度 維度,元素型別由常量池中的類引用 indexindexbyte1 << 8 + indexbyte2)標識;每個維度的尺寸由 count1, [count2, 等] 標識
N
new bb indexbyte1, indexbyte2 → objectref 建立一個型別為常量池中的類引用 indexindexbyte1 << 8 + indexbyte2)標識的新物件
newarray bc atype count → arrayref 建立一個包含 count 個由 atype 標識的原始型別元素的新陣列
nop 00 [無變化] 不執行任何操作
P
pop 57 value → 丟棄堆疊頂部的值
pop2 58 {value2, value1} → 丟棄堆疊頂部的兩個值(如果它是雙精度或長整型,則丟棄一個值)
putfield b5 indexbyte1, indexbyte2 objectref, value → value 設定為物件 objectref 中的欄位,其中欄位由常量池中的欄位引用 indexindexbyte1 << 8 + indexbyte2)標識
putstatic b3 indexbyte1, indexbyte2 value → value 設定為類中的靜態欄位,其中欄位由常量池中的欄位引用 indexindexbyte1 << 8 + indexbyte2)標識
R
ret a9 index [無變化] 從區域性變數 #index 中獲取的地址處繼續執行(與 jsr 的不對稱性是故意的)
return b1 → [空] 從方法中返回 void
S
saload 35 arrayref, index → value 從陣列中載入短整型
sastore 56 arrayref, index, value → 將短整型儲存到陣列中
sipush 11 byte1, byte2 → value 將一個帶符號的整型數(byte1 << 8 + byte2)壓入堆疊
swap 5f value2, value1 → value1, value2 交換堆疊頂部的兩個字(注意 value1 和 value2 不能是雙精度或長整型)
T
W
未用
impdep1 fe 為偵錯程式中的實現相關操作保留;不應出現在任何類檔案中
impdep2 ff 為偵錯程式中的實現相關操作保留;不應出現在任何類檔案中
(無名稱) cb-fd 這些值目前未分配給操作碼,併為將來使用保留
xxxunusedxxx ba 此操作碼“出於歷史原因”保留

參考文獻

[編輯 | 編輯原始碼]
  1. 甲骨文公司的 Java 虛擬機器規範
[編輯 | 編輯原始碼]


華夏公益教科書