1. 棧和局部變數操作 1.1 將常量壓入棧的指令 指令 功能描述 aconst_null 將null對象引用壓入棧 iconst_m1 將將int類型常量-1壓入棧 iconst_0 將int類型常量0壓入棧 iconst_1 將int類型常量1壓入棧 iconst_2 將int類型常量2壓入棧 ...
1. 棧和局部變數操作
1.1 將常量壓入棧的指令
指令 | 功能描述 |
---|---|
aconst_null | 將null對象引用壓入棧 |
iconst_m1 | 將將int類型常量-1壓入棧 |
iconst_0 | 將int類型常量0壓入棧 |
iconst_1 | 將int類型常量1壓入棧 |
iconst_2 | 將int類型常量2壓入棧 |
iconst_3 | 將int類型常量3壓入棧 |
iconst_4 | 將int類型常量4壓入棧 |
iconst_5 | 將int類型常量5壓入棧 |
lconst_0 | 將long類型常量0壓入棧 |
lconst_1 | 將long類型常量1壓入棧 |
fconst_0 | 將float類型常量0壓入棧 |
fconst_1 | 將float類型常量1壓入棧 |
dconst_0 | 將double類型常量0壓入棧 |
dconst_1 | 將double類型常量1壓入棧 |
bipush | 將一個8位帶符號整數壓入棧 |
sipush | 將16位帶符號整數壓入棧 |
ldc | 把常量池中的項壓入棧 |
ldc_w | 把常量池中的項壓入棧(使用寬索引) |
ldc2_w | 把常量池中long類型或者double類型的項壓入棧(使用寬索引) |
1.2 從棧中的局部變數中裝載值的指令
指令 | 功能描述 |
---|---|
iload | 從局部變數中裝載int類型值 |
lload | 從局部變數中裝載long類型值 |
fload | 從局部變數中裝載float類型值 |
dload | 從局部變數中裝載double類型值 |
aload | 從局部變數中裝載引用類型值(refernce) |
iload_0 | 從局部變數0中裝載int類型值 |
iload_1 | 從局部變數1中裝載int類型值 |
iload_2 | 從局部變數2中裝載int類型值 |
iload_3 | 從局部變數3中裝載int類型值 |
lload_0 | 從局部變數0中裝載long類型值 |
lload_1 | 從局部變數1中裝載long類型值 |
lload_2 | 從局部變數2中裝載long類型值 |
lload_3 | 從局部變數3中裝載long類型值 |
fload_0 | 從局部變數0中裝載float類型值 |
fload_1 | 從局部變數1中裝載float類型值 |
fload_2 | 從局部變數2中裝載float類型值 |
fload_3 | 從局部變數3中裝載float類型值 |
dload_0 | 從局部變數0中裝載double類型值 |
dload_1 | 從局部變數1中裝載double類型值 |
dload_2 | 從局部變數2中裝載double類型值 |
dload_3 | 從局部變數3中裝載double類型值 |
aload_0 | 從局部變數0中裝載引用類型值 |
aload_1 | 從局部變數1中裝載引用類型值 |
aload_2 | 從局部變數2中裝載引用類型值 |
aload_3 | 從局部變數3中裝載引用類型值 |
iaload | 從數組中裝載int類型值 |
laload | 從數組中裝載long類型值 |
faload | 從數組中裝載float類型值 |
daload | 從數組中裝載double類型值 |
aaload | 從數組中裝載引用類型值 |
baload | 從數組中裝載byte類型或boolean類型值 |
caload | 從數組中裝載char類型值 |
saload | 從數組中裝載short類型值 |
1.3 將棧中的值存入局部變數的指令
指令 | 功能描述 |
---|---|
istore | 將int類型值存入局部變數 |
lstore | 將long類型值存入局部變數 |
fstore | 將float類型值存入局部變數 |
dstore | 將double類型值存入局部變數 |
astore | 將將引用類型或returnAddress類型值存入局部變數 |
istore_0 | 將int類型值存入局部變數0 |
istore_1 | 將int類型值存入局部變數1 |
istore_2 | 將int類型值存入局部變數2 |
istore_3 | 將int類型值存入局部變數3 |
lstore_0 | 將long類型值存入局部變數0 |
lstore_1 | 將long類型值存入局部變數1 |
lstore_2 | 將long類型值存入局部變數2 |
lstore_3 | 將long類型值存入局部變數3 |
fstore_0 | 將float類型值存入局部變數0 |
fstore_1 | 將float類型值存入局部變數1 |
fstore_2 | 將float類型值存入局部變數2 |
fstore_3 | 將float類型值存入局部變數3 |
dstore_0 | 將double類型值存入局部變數0 |
dstore_1 | 將double類型值存入局部變數1 |
dstore_2 | 將double類型值存入局部變數2 |
dstore_3 | 將double類型值存入局部變數3 |
astore_0 | 將引用類型或returnAddress類型值存入局部變數0 |
astore_1 | 將引用類型或returnAddress類型值存入局部變數1 |
astore_2 | 將引用類型或returnAddress類型值存入局部變數2 |
astore_3 | 將引用類型或returnAddress類型值存入局部變數3 |
iastore | 將int類型值存入數組中 |
lastore | 將long類型值存入數組中 |
fastore | 將float類型值存入數組中 |
dastore | 將double類型值存入數組中 |
aastore | 將引用類型值存入數組中 |
bastore | 將byte類型或者boolean類型值存入數組中 |
castore | 將char類型值存入數組中 |
sastore | 將short類型值存入數組中 |
wide指令 | |
wide | 使用附加位元組擴展局部變數索引 |
1.4 通用(無類型)棧操作
指令 | 功能描述 |
---|---|
nop | 不做任何操作 |
pop | 彈出棧頂端一個字長的內容 |
pop2 | 彈出棧頂端兩個字長的內容 |
dup | 複製棧頂部一個字長內容 |
dup_x1 | 複製棧頂部一個字長的內容,然後將複製內容及原來彈出的兩個字長的內容壓入棧 |
dup_x2 | 複製棧頂部一個字長的內容,然後將複製內容及原來彈出的三個字長的內容壓入棧 |
dup2 | 複製棧頂部兩個字長內容 |
dup2_x1 | 複製棧頂部兩個字長的內容,然後將複製內容及原來彈出的三個字長的內容壓入棧 |
dup2_x2 | 複製棧頂部兩個字長的內容,然後將複製內容及原來彈出的四個字長的內容壓入棧 |
swap | 交換棧頂部兩個字長內容 |
2. 類型轉換
指令 | 功能描述 |
---|---|
i2l | 把int類型的數據轉化為long類型 |
i2f | 把int類型的數據轉化為float類型 |
i2d | 把int類型的數據轉化為double類型 |
l2i | 把long類型的數據轉化為int類型 |
l2f | 把long類型的數據轉化為float類型 |
l2d | 把long類型的數據轉化為double類型 |
f2i | 把float類型的數據轉化為int類型 |
f2l | 把float類型的數據轉化為long類型 |
f2d | 把float類型的數據轉化為double類型 |
d2i | 把double類型的數據轉化為int類型 |
d2l | 把double類型的數據轉化為long類型 |
d2f | 把double類型的數據轉化為float類型 |
i2b | 把int類型的數據轉化為byte類型 |
i2c | 把int類型的數據轉化為char類型 |
i2s | 把int類型的數據轉化為short類型 |
3. 整數運算
指令 | 功能描述 |
---|---|
iadd | 執行int類型的加法 |
ladd | 執行long類型的加法 |
isub | 執行int類型的減法 |
lsub | 執行long類型的減法 |
imul | 執行int類型的乘法 |
lmul | 執行long類型的乘法 |
idiv | 執行int類型的除法 |
ldiv | 執行long類型的除法 |
irem | 計算int類型除法的餘數 |
lrem | 計算long類型除法的餘數 |
ineg | 對一個int類型值進行取反操作 |
lneg | 對一個long類型值進行取反操作 |
iinc | 把一個常量值加到一個int類型的局部變數上 |
4. 邏輯運算
4.1 移位操作
指令 | 功能描述 |
---|---|
ishl | 執行int類型的向左移位操作 |
lshl | 執行long類型的向左移位操作 |
ishr | 執行int類型的向右移位操作 |
lshr | 執行long類型的向右移位操作 |
iushr | 執行int類型的向右邏輯移位操作 |
lushr | 執行long類型的向右邏輯移位操作 |
4.2 按位布爾運算
指令 | 功能描述 |
---|---|
iand | 對int類型值進行 |
land | 對long類型值進行“邏輯與”操作 |
ior | 對int類型值進行“邏輯或”操作 |
lor | 對long類型值進行“邏輯或”操作 |
ixor | 對int類型值進行“邏輯異或”操作 |
lxor | 對long類型值進行“邏輯異或”操作 |
4.3 浮點運算
指令 | 功能描述 |
---|---|
fadd | 執行float類型的加法 |
dadd | 執行double類型的加法 |
fsub | 執行float類型的減法 |
dsub | 執行double類型的減法 |
fmul | 執行float類型的乘法 |
dmul | 執行double類型的乘法 |
fdiv | 執行float類型的除法 |
ddiv | 執行double類型的除法 |
frem | 計算float類型除法的餘數 |
drem | 計算double類型除法的餘數 |
fneg | 將一個float類型的數值取反 |
dneg | 將一個double類型的數值取反 |
5. 對象和數組
指令 | 功能描述 |
---|
5.1 對象操作指令
指令 | 功能描述 |
---|---|
new | 創建一個新對象 |
checkcast | 確定對象為所給定的類型 |
getfield | 從對象中獲取欄位 |
putfield | 設置對象中欄位的值 |
getstatic | 從類中獲取靜態欄位 |
putstatic | 設置類中靜態欄位的值 |
instanceof | 判斷對象是否為給定的類型 |
5.2 數組操作指令
指令 | 功能描述 |
---|---|
newarray | 分配數據成員類型為基本上數據類型的新數組 |
anewarray | 分配數據成員類型為引用類型的新數組 |
arraylength | 獲取數組長度 |
multianewarray | 分配新的多維數組 |
6. 控制流
指令 | 功能描述 |
---|
6.1 條件分支指令
指令 | 功能描述 |
---|---|
ifeq | 如果等於0,則跳轉 |
ifne | 如果不等於0,則跳轉 |
iflt | 如果小於0,則跳轉 |
ifge | 如果大於等於0,則跳轉 |
ifgt | 如果大於0,則跳轉 |
ifle | 如果小於等於0,則跳轉 |
if_icmpcq | 如果兩個int值相等,則跳轉 |
if_icmpne | 如果兩個int類型值不相等,則跳轉 |
if_icmplt | 如果一個int類型值小於另外一個int類型值,則跳轉 |
if_icmpge | 如果一個int類型值大於或者等於另外一個int類型值,則跳轉 |
if_icmpgt | 如果一個int類型值大於另外一個int類型值,則跳轉 |
if_icmple | 如果一個int類型值小於或者等於另外一個int類型值,則跳轉 |
ifnull | 如果等於null,則跳轉 |
ifnonnull | 如果不等於null,則跳轉 |
if_acmpeq | 如果兩個對象引用相等,則跳轉 |
if_acmpnc | 如果兩個對象引用不相等,則跳轉 |
6.2 比較指令
指令 | 功能描述 |
---|---|
lcmp | 比較long類型值 |
fcmpl | 比較float類型值(當遇到NaN時,返回-1) |
fcmpg | 比較float類型值(當遇到NaN時,返回1) |
dcmpl | 比較double類型值(當遇到NaN時,返回-1) |
dcmpg | 比較double類型值(當遇到NaN時,返回1) |
6.3 無條件轉移指令
指令 | 功能描述 |
---|---|
goto | 無條件跳轉 |
goto_w | 無條件跳轉(寬索引) |
6.4 表跳轉指令
指令 | 功能描述 |
---|---|
tableswitch | 通過索引訪問跳轉表,並跳轉 |
lookupswitch | 通過鍵值匹配訪問跳轉表,並執行跳轉操作 |
6.5 異常
指令 | 功能描述 |
---|---|
athrow | 拋出異常或錯誤 |
finally子句 | |
jsr | 跳轉到子常式 |
jsr_w | 跳轉到子常式(寬索引) |
rct | 從子常式返回 |
7. 方法調用與返回
7.1 方法調用指令
指令 | 功能描述 |
---|---|
invokcvirtual | 運行時按照對象的類來調用實例方法 |
invokespecial | 根據編譯時類型來調用實例方法 |
invokestatic | 調用類(靜態)方法 |
invokcinterface | 調用介面方法 |
7.2 方法返回指令
指令 | 功能描述 |
---|---|
ireturn | 從方法中返回int類型的數據 |
lreturn | 從方法中返回long類型的數據 |
freturn | 從方法中返回float類型的數據 |
dreturn | 從方法中返回double類型的數據 |
areturn | 從方法中返回引用類型的數據 |
return | 從方法中返回,返回值為void |
7.3 線程同步
指令 | 功能描述 |
---|---|
montiorenter | 進入並獲取對象監視器 |
monitorexit | 釋放並退出對象監視器 |
如何根據以上指令手冊翻譯java源碼呢?
首先新建一個java類,這裡用DemoForJavap.java舉個例,源碼如下:
package com.example.demo;
public class DemoForJavap{
public int add(){
int a = 1;
int b = 2;
int c = a+b;
return c;
}
}
使用javac命令編譯成class文件後用javap -c命令進行反彙編
我們主要解讀下add這個方法中的彙編碼:
public int add();
Code:
0: iconst_1 //將int類型常量1壓入操作數棧
1: istore_1 //將int類型值存入局部變數1,此處相當於int a=1;執行完畢
2: iconst_2 //將int類型常量2壓入操作數棧
3: istore_2 //將int類型值存入局部變數2,此處相當於int b=2;執行完畢
4: iload_1 //從局部變數1中裝載int類型值
5: iload_2 //從局部變數2中裝載int類型值
6: iadd //執行int類型的加法
7: istore_3 //將int類型值存入局部變數3,此處相當於int c=a+b;執行完畢
8: iload_3 //從局部變數3中裝載int類型值
9: ireturn //從方法中返回int類型的數據,此處相當於return c;執行完畢