整體設計
- 機器模型和呼叫約定旨在近似模仿常見的真實架構和 C 風格的呼叫約定:
- 該機器是基於寄存器的,並且幀在創建時尺寸是固定的。每個幀由特定數量的暫存器(由方法指定)以及執行該方法所需的任何附加資料組成,例如(但不限於)程式計數器和對包含該方法的
.dex
檔案的引用。 - 當用於位元值(例如整數和浮點數)時,暫存器被視為 32 位元寬。相鄰暫存器對用於 64 位元值。寄存器對沒有對齊要求。
- 當用於物件引用時,暫存器被認為足夠寬以恰好容納一個這樣的引用。
- 從位元表示的角度來看,
(Object) null == (int) 0
。 - 方法的N 個參數依序存放在方法呼叫訊框的最後N 個暫存器。寬參數消耗兩個暫存器。實例方法傳遞
this
引用作為其第一個參數。
- 該機器是基於寄存器的,並且幀在創建時尺寸是固定的。每個幀由特定數量的暫存器(由方法指定)以及執行該方法所需的任何附加資料組成,例如(但不限於)程式計數器和對包含該方法的
- 指令流中的儲存單元是一個16位元無符號數。某些指令中的某些位元被忽略/必須為零。
- 指令並非無緣無故限制於特定類型。例如,無需解釋即可移動 32 位元暫存器值的指令不必指定它們是移動整數還是浮點數。
- 對於字串、類型、欄位和方法的引用,有單獨的枚舉和索引常數池。
- 按位文字資料在指令流中內聯表示。
- 因為在實務上,一種方法需要超過 16 個暫存器的情況並不常見,而且因為需要超過 8 個暫存器的情況相當常見,所以許多指令僅限於尋址前 16 個暫存器。在合理的情況下,指令允許引用最多前 256 個暫存器。此外,某些指令具有允許更大暫存器計數的變體,包括一對可以定址
v0
–v65535
範圍內的暫存器的包羅萬象的move
指令。如果指令變體不可用於尋址所需的暫存器,則期望暫存器內容從原始暫存器移動到低位元暫存器(在操作之前)和/或從低位結果暫存器移動到高位結果暫存器。註冊(操作後)。 - 有幾個「偽指令」用於保存可變長度資料有效負載,它們由常規指令引用(例如
fill-array-data
)。在正常執行流程中絕對不能遇到此類指令。此外,指令必須位於偶數位節碼偏移量上(即 4 位元組對齊)。為了滿足此要求,dex 產生工具必須發出額外的nop
指令作為間隔符號(如果此類指令未對齊)。最後,儘管不是必需的,但預計大多數工具將選擇在方法末尾發出這些指令,因為否則可能會出現需要額外的指令來圍繞它們進行分支的情況。 - 當安裝在正在運行的系統上時,一些指令可能會被更改,改變它們的格式,作為安裝時靜態連結最佳化。這是為了在已知連結後可以更快地執行。請參閱相關的指令格式文件以了解建議的變體。 「建議」一詞是經過深思熟慮後使用的;實施這些並不是強制性的。
- 人類語法和助記符:
- 參數的先到後源排序。
- 一些操作碼具有消除歧義的名稱後綴來指示它們操作的類型:
- 通用類型 32 位元操作碼未標記。
- 通用類型 64 位元操作碼帶有
-wide
後綴。 - 特定於類型的操作碼以其類型(或簡單的縮寫)為後綴,為以下之一:
-boolean
-byte
-char
-short
-int
-long
-float
-double
-object
-string
-class
-void
。
- 有些操作碼具有消除歧義的後綴,以區分具有不同指令佈局或選項的其他相同操作。這些後綴與主名稱之間用斜杠(“
/
”)分隔,主要是為了在生成和解釋可執行檔的程式碼中與靜態常數進行一對一映射(即減少歧義)對於人類)。 - 在這裡的描述中,透過每四位寬度使用一個字元來強調值的寬度(指示例如常數的範圍或可能尋址的暫存器的數量)。
- 例如,在指令「
move-wide/from16 vAA, vBBBB
」:- 「
move
」是基本操作碼,表示基本操作(移動暫存器的值)。 - 「
wide
」是名稱後綴,表示它對寬(64 位元)資料進行操作。 - 「
from16
」是操作碼後綴,表示以 16 位元暫存器引用作為來源的變體。 - 「
vAA
」 是目標暫存器(由操作隱含;同樣,規則是目標參數永遠先出現),它必須在v0
–v255
範圍內。 - 「
vBBBB
」是來源暫存器,它必須在v0
–v65535
範圍內。
- 「
- 有關各種指令格式(在“操作和格式”下列出)的更多詳細信息以及有關操作碼語法的詳細信息,請參閱指令格式文檔。
- 有關字節碼在更大範圍內的位置的更多詳細信息,請參閱
.dex
文件格式文檔。
字節碼集總結
操作與格式 | 助記符/文法 | 論點 | 描述 |
---|---|---|---|
00 10x | 不 | 廢物循環。 注意:承載資料的偽指令以該操作碼標記,在這種情況下,操作碼單元的高位元組指示資料的性質。請參閱下方的「 | |
01 12x | 移動 vA, vB | A: 目標暫存器(4位元)B: 來源暫存器(4位) | 將一個非物件暫存器的內容移到另一個非物件暫存器。 |
02 22x | 移動/來自16 vAA, vBBBB | A: 目標暫存器(8 位元)B: 來源暫存器(16位元) | 將一個非物件暫存器的內容移到另一個非物件暫存器。 |
03 32x | 移動/16 vAAAA, vBBBB | A: 目標暫存器(16 位元)B: 來源暫存器(16位元) | 將一個非物件暫存器的內容移到另一個非物件暫存器。 |
04 12x | 移動範圍 vA, vB | A: 目標暫存器對(4 位元)B: 來源暫存器對(4位) | 將一個寄存器對的內容移至另一對。 注意:從 |
05 22x | 移動範圍/from16 vAA, vBBBB | A: 目標暫存器對(8 位元)B: 來源暫存器對(16位元) | 將一個寄存器對的內容移至另一對。 注意:實施注意事項與上面的 |
06 32x | 移動範圍/16 vAAAA、vBBBB | A: 目標暫存器對(16 位元)B: 來源暫存器對(16位元) | 將一個寄存器對的內容移至另一對。 注意:實施注意事項與上面的 |
07 12x | 移動物件 vA, vB | A: 目標暫存器(4位元)B: 來源暫存器(4位) | 將一個物件承載暫存器的內容移到另一個。 |
08 22x | 移動物件/from16 vAA、vBBBB | A: 目標暫存器(8 位元)B: 來源暫存器(16位元) | 將一個物件承載暫存器的內容移到另一個。 |
09 32x | 移動物件/16 vAAAA、vBBBB | A: 目標暫存器(16位元)B: 來源暫存器(16位元) | 將一個物件承載暫存器的內容移到另一個。 |
0a 11x | 移動結果 vAA | A: 目標暫存器(8 位元) | 將最近invoke- kind 的單字非物件結果移到指定的暫存器。這必須作為緊接在其(單字、非物件)結果不可被忽略的invoke- kind 之後的指令來完成;其他地方均無效。 |
0b 11x | 移動結果範圍內的 vAA | A: 目標暫存器對(8 位元) | 將最近invoke- kind 的雙字結果移至指定的暫存器對中。這必須作為緊接在其(雙字)結果不可被忽略的invoke- kind 之後的指令來完成;其他地方均無效。 |
0c 11x | 移動結果對象 vAA | A: 目標暫存器(8 位元) | 將最近invoke- kind 的物件結果移動到指定的暫存器。這必須作為緊接在invoke- kind 或filled-new-array 之後的指令來完成,其(物件)結果不可被忽略;其他地方均無效。 |
0d 11x | 移動異常 vAA | A: 目標暫存器(8 位元) | 將剛剛捕獲的異常保存到給定的暫存器中。這必須是任何捕獲到的異常不會被忽略的異常處理程序的第一條指令,並且該指令只能作為異常處理程序的第一條指令出現;其他地方均無效。 |
0e 10x | 回傳無效 | 從void 方法返回。 | |
0f 11x | 返回vAA | A: 傳回值暫存器(8位元) | 從單寬度(32 位元)非物件值傳回方法傳回。 |
10 11x | 返回範圍的 vAA | A: 傳回值暫存器對(8 位元) | 從雙寬度(64 位元)值返回方法返回。 |
11 11x | 回傳對象 vAA | A: 傳回值暫存器(8位元) | 從物件返回方法返回。 |
12 11n | 常數/4 vA,#+B | A: 目標暫存器(4位元)B: 有符號整數(4 位元) | 將給定的文字值(符號擴展為 32 位元)移至指定的暫存器中。 |
13 21 秒 | 常數/16 vAA,#+BBBB | A: 目標暫存器(8 位元)B: 有符號整數(16 位元) | 將給定的文字值(符號擴展為 32 位元)移至指定的暫存器中。 |
14 31i | 常量 vAA, #+BBBBBBBB | A: 目標暫存器(8 位元)B: 任32位元常數 | 將給定的文字值移入指定的暫存器。 |
15 21 點 | 常量/高16 vAA,#+BBBB0000 | A: 目標暫存器(8 位元)B: 有符號整數(16 位元) | 將給定的文字值(右零擴展為 32 位元)移入指定的暫存器。 |
16 21 秒 | 常量寬/16 vAA,#+BBBB | A: 目標暫存器(8 位元)B: 有符號整數(16 位元) | 將給定的文字值(符號擴展為 64 位元)移至指定的暫存器對中。 |
17 31i | 常量寬/32 vAA,#+BBBBBBBB | A: 目標暫存器(8 位元)B: 有符號整數(32 位元) | 將給定的文字值(符號擴展為 64 位元)移至指定的暫存器對中。 |
18 51升 | 常數範圍 vAA,#+BBBBBBBBBBBBBBBB | A: 目標暫存器(8 位元)B: 任雙角(64 位元)常數 | 將給定的文字值移入指定的暫存器對。 |
19 21 點 | 常量寬/高16 vAA,#+BBBB000000000000 | A: 目標暫存器(8 位元)B: 有符號整數(16 位元) | 將給定的文字值(右零擴展為 64 位元)移到指定的暫存器對中。 |
1a 21c | 常數字串 vAA,字串@BBBB | A: 目標暫存器(8 位元)B: 字串索引 | 將給定索引指定的字串的參考移至指定的暫存器。 |
1b 31c | 常數字串/巨型 vAA,字串@BBBBBBBB | A: 目標暫存器(8 位元)B: 字串索引 | 將給定索引指定的字串的參考移至指定的暫存器。 |
1c 21c | 常量類 vAA,類型@BBBB | A: 目標暫存器(8 位元)B: 類型索引 | 將給定索引指定的類別的參考移至指定的暫存器。在指示的類型是原始類型的情況下,這將儲存對原始類型的簡併類別的參考。 |
1d 11x | 監控輸入 vAA | A: 參考承載暫存器(8 位元) | 取得指定物件的監視器。 |
1e 11x | 監控出口 vAA | A: 參考承載暫存器(8 位元) | 釋放指定物件的監視器。 注意:如果該指令需要拋出異常,則必須像 PC 已經超越該指令一樣進行操作。將其視為指令成功執行(在某種意義上),並且在該指令之後但在下一條指令有機會運行之前拋出異常可能會很有用。此定義使得方法可以使用監視器清理包羅萬象(例如, |
1f 21c | 檢查投射 vAA,輸入@BBBB | A: 參考承載暫存器(8 位元)B: 類型索引(16位元) | 如果給定暫存器中的參考無法轉換為指示的類型,則拋出ClassCastException 。注意:由於 |
20 22c | vA、vB 的實例,類型@CCCC | A: 目標暫存器(4位元)B: 參考承載暫存器(4 位元)C: 類型索引(16位元) | 如果指示的參考是給定類型的實例,則在給定的目標暫存器中儲存1 ,否則儲存0 。注意:由於 |
21 12x | 數組長度 vA, vB | A: 目標暫存器(4位元)B: 數組引用暫存器(4 位元) | 在給定的目標暫存器中儲存指定數組的長度(以條目為單位) |
22 21c | 新實例 vAA,類型@BBBB | A: 目標暫存器(8 位元)B: 類型索引 | 建構指定類型的新實例,並將對其的參考儲存在目標中。該型別必須引用非數組類別。 |
23 22c | 新數組 vA、vB、類型@CCCC | A: 目標暫存器(4位元)B: 尺寸寄存器C: 類型索引 | 建構一個指定型別和大小的新陣列。該類型必須是數組類型。 |
24 35c | 填入新數組 {vC, vD, vE, vF, vG}, type@BBBB | A: 陣列大小和參數字數(4 位元)B: 類型索引(16位元)C..G: 參數暫存器(每個 4 位元) | 建構一個給定類型和大小的數組,並用提供的內容填充它。該類型必須是數組類型。數組的內容必須是單字(即,不能是long 或double 數組,但可以接受引用類型)。建構的實例以與方法呼叫指令儲存其結果相同的方式儲存為“結果”,因此必須使用緊接著的move-result-object 指令將建構的實例移到暫存器(如果要使用它) )。 |
25 3rc | 填入新數組/範圍 {vCCCC .. vNNNN},類型@BBBB | A: 陣列大小和參數字數(8 位元)B: 類型索引(16位元)C: 第一個參數暫存器(16 位元)N = A + C - 1 | 建構一個給定類型和大小的數組,並用提供的內容填充它。說明和限制與上述的filled-new-array 相同。 |
26 31噸 | fill-array-data vAA,+BBBBBBBB (具有下方「 fill-array-data-payload 格式」中指定的補充資料) | A: 陣列引用(8位元)B: 表資料偽指令的有符號「分支」偏移量(32 位元) | 用指定的資料填入給定的陣列。該引用必須是對基元數組的引用,並且資料表必須在類型上與其匹配,並且包含的元素不多於數組所能容納的元素。也就是說,陣列可能比表大,如果是這樣,則僅設定陣列的初始元素,而保留其餘元素。 |
27 11x | 投擲vAA | A: 異常承載暫存器(8位元) | 拋出指定的例外。 |
28 10噸 | 前往+AA | A: 有符號分支偏移量(8 位元) | 無條件跳到指定指令。 注意:分支偏移量不能為 |
29 20噸 | 轉到/16 +AAAA | A: 有符號分支偏移量(16 位元) | 無條件跳到指定指令。 注意:分支偏移量不能為 |
2a 30t | 轉到/32 +AAAAAAAA | A: 有符號分支偏移量(32 位元) | 無條件跳到指定指令。 |
2b 31t | Packed-switch vAA、+BBBBBBBB (具有以下「 packed-switch-payload 格式」中指定的補充資料) | A: 註冊測試B: 表資料偽指令的有符號「分支」偏移量(32 位元) | 使用與特定整數範圍內的每個值相對應的偏移量表,根據給定暫存器中的值跳到新指令,或者如果不匹配則跳到下一指令。 |
2c 31t | 稀疏開關 vAA,+BBBBBBBB (具有下面“ sparse-switch-payload 格式”中指定的補充資料) | A: 註冊測試B: 表資料偽指令的有符號「分支」偏移量(32 位元) | 使用值偏移對的有序表,根據給定暫存器中的值跳到新指令,如果沒有匹配,則跳到下一指令。 |
2d..31 23x | cmp類型vAA、vBB、vCC 2d:cmpl-float (lt 偏差) 2e:cmpg-float (gt 偏差) 2f:cmpl-double (lt 偏差) 30:cmpg-double (gt 偏差) 31: cmp 長 | A: 目標暫存器(8 位元)B: 第一個來源暫存器或對C: 第二個來源暫存器或對 | 執行指示的浮點或long 比較,如果b == c 將a 設為0 ,如果b > c ,則設為1 ,如果b < c ,則設定-1 。為浮點運算所列出的「bias」指示如何處理NaN 比較:對於NaN 比較,「gtbias」指令傳回1 ,而「ltbias」指令傳回-1 。例如,要檢查浮點數是否 |
32..37 22噸 | if-測試vA、vB、+CCCC 32:如果-eq 33:如果-不 34:如果-lt 35:如果-ge 36:如果-gt 37:如果-le | A: 第一個要測試的暫存器(4位元)B: 要測試的第二個暫存器(4 位元)C: 有符號分支偏移量(16 位元) | 如果給定的兩個暫存器的值按指定進行比較,則轉移到給定的目標。 注意:分支偏移量不能為 |
38..3d 21t | if-測試z vAA, +BBBB 38:if-eqz 39:如果-鼻 3a:如果-ltz 3b:if-gez 3c:if-gtz 3d:如果-lez | A: 要測試的暫存器(8位元)B: 有符號分支偏移量(16 位元) | 如果給定暫存器的值與指定的 0 進行比較,則轉移到給定目標。 注意:分支偏移量不能為 |
3e..43 10x | (沒用過) | (沒用過) | |
44..51 23x | arrayop vAA、vBB、vCC 44:阿傑 45:全年齡段 46:aget對象 47:aget布林值 48: 取得位元組 49:aget-char 4a:年齡短 4b: aput 4c:aput範圍 4d: aput-對象 4e:aput-布林值 4f: aput 位元組 50: aput 字符 51:aput-short | A: 值暫存器或值對;可以是來源或目標(8 位元)B: 數組暫存器(8位)C: 變址暫存器(8位元) | 在給定數組的已識別索引處執行已識別數組操作,載入或儲存到值暫存器中。 |
52..5f 22c | i實例操作vA、vB、field@CCCC 52:我得到 53:全iget 54: iget 對象 55: iget布林值 56: iget 字節 57: iget 字符 58:iget-短 59:輸入 5a:輸入範圍 5b:輸入對象 5c:輸入布林值 5d:輸入位元組 5e: 輸入字符 5f:輸入短路 | A: 值暫存器或值對;可以是來源或目標(4 位元)B: 物件暫存器(4位元)C: 實例欄位引用索引(16位元) | 對所識別的欄位執行所識別的物件實例欄位操作,載入或儲存到值暫存器中。 注意:這些操作碼是靜態連結的合理候選者,將欄位參數變更為更直接的偏移量。 |
60..6d 21c | s staticop vAA,field@BBBB 60:sget 61:整個群體 62: sget 對象 63:sget布林值 64: sget 字節 65: sget 字符 66:短的 67:吐痰 68:全範圍 69:sput對象 6a:sput-布林值 6b:輸出位元組 6c:sput-char 6d:濺鍍短路 | A: 值暫存器或值對;可以是來源或目標(8 位元)B: 靜態欄位引用索引(16位元) | 對所識別的靜態欄位執行所識別的物件靜態欄位操作,載入或儲存到值暫存器中。 注意:這些操作碼是靜態連結的合理候選者,將欄位參數變更為更直接的偏移量。 |
6e..72 35c | 呼叫類型{vC, vD, vE, vF, vG}, meth@BBBB 6e:呼叫虛擬 6f:呼叫超級 70:直接調用 71:調用靜態 72:呼叫接口 | A: 參數字數(4 位元)B: 方法參考索引(16位元)C..G: 參數暫存器(每個 4 位元) | 呼叫指定的方法。結果(如果有)可以與適當的move-result* 變體一起儲存作為緊接著的後續指令。 當 在 Dex 檔案版本 注意:這些操作碼是靜態連結的合理候選者,將方法參數變更為更直接的偏移量(或其對)。 |
73 10x | (沒用過) | (沒用過) | |
74..78 3rc | 調用-種類/範圍{vCCCC .. vNNNN},meth@BBBB 74:呼叫虛擬/範圍 75:呼叫超級/範圍 76:調用直接/範圍 77:調用靜態/範圍 78:呼叫介面/範圍 | A: 參數字數(8 位元)B: 方法參考索引(16位元)C: 第一個參數暫存器(16 位元)N = A + C - 1 | 呼叫指定的方法。有關詳細資訊、注意事項和建議,請參閱上面的第一個invoke- kind 描述。 |
79..7a 10x | (沒用過) | (沒用過) | |
7b..8f 12x | UNOP vA, vB 7b:負整型 7c:非整數 7d:負長 7e:不長 7f:負浮點數 80:負雙 81:整數到長整型 82:整數到浮點 83:整數到雙精度 84:長整型 85:長期漂浮 86:長到雙倍 87:浮點數轉整數 88:浮動到長 89:浮動到雙精度 8a:雙精度型到整數型 8b:雙倍到長整型 8c:雙浮點 8d:整數到位元組 8e:int 到 char 8f:整數到短 | A: 目標暫存器或對(4 位元)B: 來源暫存器或對(4 位元) | 對來源暫存器執行識別的一元運算,將結果儲存在目標暫存器中。 |
90..af 23x | 比諾普vAA、vBB、vCC 90:添加 91:子整數 92: 多整數 93:div-int 94:rem-int 95:和-整數 96: 或-int 97: 異或整數 98:shl-int 99:shr-int 9a:ushr-int 9b:加長 9c:亞長 9d:穆隆 9e:div-長 9f:雷姆-長 a0: 和-長 a1: 或長 a2:異或長 a3: shl-長 a4: shr-長 a5: ushr-長 a6:新增浮動 a7:子浮點 a8:乘法浮點數 a9: div 浮點 aa: rem 浮點 ab:加倍 ac:亞雙 ad:乘法 ae: div-雙精度 af: rem-雙 | A: 目標暫存器或對(8 位元)B: 第一個來源暫存器或對(8 位元)C: 第二個來源暫存器或對(8 位元) | 對兩個來源暫存器執行識別的二進位運算,將結果儲存到目標暫存器中。 注意:與其他 |
b0..cf 12x | binop /2addr vA, vB b0:add-int/2addr b1: 子整數/2addr b2: mul-int/2addr b3: div-int/2addr b4: rem-int/2addr b5:and-int/2addr b6: 或-int/2addr b7: 異或整數/2addr b8: shl-int/2addr b9: shr-int/2addr ba: ushr-int/2addr bb:add-long/2addr bc: 子長/2addr bd: mul-long/2addr 為:div-long/2addr bf: rem-long/2addr c0: and-long/2addr c1: 或-long/2addr c2: 異或長/2addr c3: shl-長/2addr c4: shr-long/2addr c5: ushr-long/2addr c6: 新增浮點/2addr c7: 子浮點/2addr c8: mul-float/2addr c9: div-float/2addr ca: rem-float/2addr cb:add-double/2addr 抄送:子雙精度/2addr cd: 乘法雙精確度/2addr ce:div-double/2addr cf: rem-double/2addr | A: 目標和第一個來源暫存器或對(4 位元)B: 第二個來源暫存器或對(4 位元) | 對兩個來源暫存器執行識別的二進位運算,將結果儲存在第一個來源暫存器中。 注意:與其他 |
d0..d7 22秒 | binop /lit16 vA、vB、#+CCCC d0: 新增 int/lit16 d1:rsub-int(反向減法) d2: mul-int/lit16 d3:div-int/lit16 d4: rem-int/lit16 d5:and-int/lit16 d6: 或-int/lit16 d7: 異或整數/lit16 | A: 目標暫存器(4位元)B: 來源暫存器(4位)C: 有符號整數常數(16 位元) | 對指定暫存器(第一個參數)和文字值(第二個參數)執行指定的二進位操作,將結果儲存在目標暫存器中。 注意: |
d8..e2 22b | binop /lit8 vAA、vBB、#+CC d8: 新增 int/lit8 d9: rsub-int/lit8 da: mul-int/lit8 db:div-int/lit8 dc: rem-int/lit8 dd: 和-int/lit8 de: or-int/lit8 df: 異或整數/lit8 e0: shl-int/lit8 e1: shr-int/lit8 e2: ushr-int/lit8 | A: 目標暫存器(8 位元)B: 來源暫存器(8位)C: 有符號整數常數(8 位元) | 對指定暫存器(第一個參數)和文字值(第二個參數)執行指定的二進位操作,將結果儲存在目標暫存器中。 注意:有關 |
e3..f9 10x | (沒用過) | (沒用過) | |
發45cc | 呼叫多態 {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH | A: 參數字數(4 位元)B: 方法參考索引(16位元)C: 接收器(4位元)D..G: 參數暫存器(每個 4 位元)H: 原型參考索引(16位元) | 呼叫指定的簽章多型方法。結果(如果有)可以與適當的move-result* 變體一起儲存作為緊接著的後續指令。方法參考必須是簽章多型方法,例如 java.lang.invoke.MethodHandle.invoke 或java.lang.invoke.MethodHandle.invokeExact 。接收者必須是支援所呼叫的簽章多型方法的物件。 原型參考描述了提供的參數類型和預期的返回類型。 invoke-polymorphic 字節碼在執行時可能會引發異常。 API 文件中描述了所呼叫的簽章多型方法的異常情況。從版本 038 開始出現在 Dex 檔案中。 |
FB 4RCC | 呼叫多態性/範圍 {vCCCC .. vNNNN},meth@BBBB,proto@HHHH | A: 參數字數(8 位元)B: 方法參考索引(16位元)C: 接收器(16位元)H: 原型參考索引(16位元)N = A + C - 1 | 呼叫指定的方法句柄。有關詳細信息,請參閱上面的invoke-polymorphic 描述。從版本 038 開始出現在 Dex 檔案中。 |
FC 35c | 呼叫自訂 {vC、vD、vE、vF、vG},call_site@BBBB | A: 參數字數(4 位元)B: 呼叫站點參考索引(16 位元)C..G: 參數暫存器(每個 4 位元) | 解析並呼叫指定的呼叫站點。呼叫的結果(如果有)可以與適當的move-result* 變體一起儲存作為緊接著的後續指令。此指令分兩個階段執行:呼叫網站解析和呼叫網站呼叫。 呼叫站點解析檢查指示的呼叫站點是否具有關聯的 java.lang.invoke.CallSite 實例。如果沒有,則使用 DEX 檔案中存在的參數呼叫指定呼叫網站的引導連結器方法(請參閱call_site_item )。引導連結器方法傳回一個java.lang.invoke.CallSite 實例,如果不存在關聯,則該實例將與指定的呼叫站點關聯。另一個執行緒可能已經先建立了關聯,如果是這樣,指令的執行將繼續執行第一個關聯的java.lang.invoke.CallSite 實例。呼叫站點呼叫是在已解析的 java.lang.invoke.CallSite 實例的java.lang.invoke.MethodHandle 目標上進行的。呼叫目標就像使用方法句柄和invoke-custom 指令的參數作為精確方法句柄呼叫的參數執行invoke-polymorphic (如上所述)一樣。bootstrap 連結器方法引發的例外狀況包含在 java.lang.BootstrapMethodError 中。如果出現以下情況,也會引發BootstrapMethodError :
038 開始出現在 Dex 檔案中。 |
FD 3RC | 呼叫自訂/範圍 {vCCCC .. vNNNN},call_site@BBBB | A: 參數字數(8 位元)B: 呼叫站點參考索引(16位元)C: 第一個參數暫存器(16 位元)N = A + C - 1 | 解析並調用調用站點。有關詳細信息,請參閱上面的invoke-custom 描述。從版本 038 開始出現在 Dex 檔案中。 |
鐵21c | 常數方法句柄 vAA,method_handle@BBBB | A: 目標暫存器(8 位元)B: 方法句柄索引(16位元) | 將給定索引指定的方法句柄的參考移至指定的暫存器。 從版本 039 開始出現在 Dex 檔案中。 |
FF 21C | const 方法類型 vAA,proto@BBBB | A: 目標暫存器(8 位元)B: 方法原型參考(16位) | 將給定索引指定的方法原型的參考移至指定的暫存器。 從版本 039 開始出現在 Dex 檔案中。 |
打包交換有效負載格式
姓名 | 格式 | 描述 |
---|---|---|
身分 | u短= 0x0100 | 辨識偽操作碼 |
尺寸 | 超短 | 表中的條目數 |
第一個鍵 | 整數 | 第一個(也是最低的)switch case 值 |
目標 | 整數[] | 相對分支目標size 的列表。目標與 switch 操作碼的位址相關,而不是與該表的位址相關。 |
注意:此表的實例的代碼單元總數為(size * 2) + 4
。
稀疏開關有效負載格式
姓名 | 格式 | 描述 |
---|---|---|
身分 | u短= 0x0200 | 辨識偽操作碼 |
尺寸 | 超短 | 表中的條目數 |
鍵 | 整數[] | size 鍵值列表,從低到高排序 |
目標 | 整數[] | size 相對分支目標的列表,每個目標對應於同一索引處的鍵值。目標與 switch 操作碼的位址相關,而不是與該表的位址相關。 |
注意:此表的實例的代碼單元總數為(size * 4) + 2
。
填入數組資料有效負載格式
姓名 | 格式 | 描述 |
---|---|---|
身分 | 短整型 = 0x0300 | 辨識偽操作碼 |
元素寬度 | 超短 | 每個元素的位元組數 |
尺寸 | 單位 | 表中的元素數量 |
數據 | 優字節[] | 數據值 |
注意:此表的實例的代碼單元總數為(size * element_width + 1) / 2 + 4
。
數學運算細節
注意:除非另有說明,浮點運算必須遵循 IEEE 754 規則,使用舍入到最近值和漸進下溢。
操作碼 | C語意 | 筆記 |
---|---|---|
負整型 | int32a; int32 結果 = -a; | 一元補碼。 |
非整數 | int32a; int32 結果 = ~a; | 一元補碼。 |
負長 | int64 一個; int64 結果 = -a; | 一元補碼。 |
不久 | int64 一個; int64 結果 = ~a; | 一元補碼。 |
負浮動 | 浮動一個; 浮點結果=-a; | 浮點求反。 |
負雙 | 雙a; 雙結果=-a; | 浮點求反。 |
整數到長型 | int32a; int64 結果 = (int64) a; | 將int32 的擴充簽到int64 。 |
int-to-loplat | int32 a; float結果=(float)a; | 使用圓頭到達的最新轉換int32 向float 。對於某些值,這將失去精度。 |
int to-to-double | int32 a; 雙重結果=(double)a; | 將int32 轉換為double 。 |
遠處 | int64 a; int32結果=(int32)a; | int64 將其截斷為int32 。 |
長期流動 | int64 a; float結果=(float)a; | 使用圓頭到達的最新轉換int64 向float 。對於某些值,這將失去精度。 |
長到雙 | int64 a; 雙重結果=(double)a; | 使用圓頭到達的最終轉換int64 double 。對於某些值,這將失去精度。 |
浮動到印度 | 浮動a; int32結果=(int32)a; | 使用圓形 - toward-Zero將float 轉換為int32 。 NaN 和-0.0 (負零)轉換為整數0 。根據符號的不同-0x80000000 0x7fffffff 和值太大而無法代表代表。 |
浮動到長 | 浮動a; int64結果=(int64)a; | 使用圓形toward-Zero將float 轉換為int64 。與float-to-int 相同的特殊情況規則在此處應用,除了範圍外值轉換為0x7fffffffffffffff 或-0x8000000000000000 ,具體取決於簽名。 |
浮動對雙 | 浮動a; 雙重結果=(double)a; | 將float 轉換為double ,準確保留值。 |
雙到in | 雙a; int32結果=(int32)a; | 使用圓形零件零,將double 轉換為int32 。與float-to-int 相同的特殊案例規則在此適用。 |
雙到長 | 雙a; int64結果=(int64)a; | 使用圓形零件零,將double 轉換為int64 。與float-to-long 相同的特殊案例規則在此適用。 |
雙流動性 | 雙a; float結果=(float)a; | 使用double 到達的最終轉換為float 。對於某些值,這將失去精度。 |
int to byte | int32 a; int32結果=(a << 24)>> 24; | int32 至int8 的截斷,簽名以擴展結果。 |
int-to-char | int32 a; int32結果= a&0xffff; | int32 截斷至uint16 ,無符號擴充。 |
int | int32 a; int32結果=(a << 16)>> 16; | int32 至int16 的截斷,符號擴展結果。 |
添加 | int32 a,b; int32結果= a + b; | 二十套添加。 |
sub-Int | int32 a,b; int32結果= a -b; | 兩次匯總減法。 |
rsub-in | int32 a,b; int32結果= b -a; | 兩次彙編反向減法。 |
mul-int | int32 a,b; int32結果= a * b; | 二十二個組合乘法。 |
Div-Int | int32 a,b; int32結果= a / b; | 兩次組合的劃分,朝零(即,被截斷為整數)。如果b == 0 ,這將引發ArithmeticException 。 |
rem-Int | int32 a,b; int32結果= a%b; | 劃分後的剩餘剩餘時間。結果的符號與a 的符號相同,並且更精確地定義為result == a - (a / b) * b 。如果b == 0 ,這將引發ArithmeticException 。 |
和int | int32 a,b; INT32結果= A&B; | 鑽頭和。 |
或者 | int32 a,b; int32結果= a | b; | 鑽頭或。 |
XOR-INT | int32 a,b; int32結果= a ^ b; | 位元XOR。 |
shl-int | int32 a,b; int32結果= a <<(b&0x1f); | 左側移動(有蒙版的參數)。 |
shr-Int | int32 a,b; int32結果= a >>(b&0x1f); | 位元簽名的偏移右(帶有蒙版參數)。 |
USHR-INT | uint32 a,b; int32結果= a >>(b&0x1f); | 位於無符號移動右(帶有蒙版參數)。 |
加長 | int64 a,b; int64結果= a + b; | 二十套添加。 |
長 | int64 a,b; int64結果= a -b; | 兩次匯總減法。 |
mul-long | int64 a,b; int64結果= a * b; | 二十二個組合乘法。 |
Div-long | int64 a,b; int64結果= a / b; | 兩次組合的劃分,朝零(即,被截斷為整數)。如果b == 0 ,這將引發ArithmeticException 。 |
雷長 | int64 a,b; int64結果= a%b; | 劃分後的剩餘剩餘時間。結果的符號與a 的符號相同,並且更精確地定義為result == a - (a / b) * b 。如果b == 0 ,這將引發ArithmeticException 。 |
長 | int64 a,b; INT64結果= A&B; | 鑽頭和。 |
長 | int64 a,b; int64結果= a | b; | 鑽頭或。 |
xor-long | int64 a,b; int64結果= a ^ b; | 位元XOR。 |
shl-long | int64 a; int32 b; int64結果= a <<(b&0x3f); | 左側移動(有蒙版的參數)。 |
Shr-long | int64 a; int32 b; int64結果= a >>(b&0x3f); | 位元簽名的偏移右(帶有蒙版參數)。 |
USHR-LONG | uint64 a; int32 b; int64結果= a >>(b&0x3f); | 位於無符號移動右(帶有蒙版參數)。 |
添加流動 | float a,b; 浮點結果= a + b; | 浮點增加。 |
子浮動 | float a,b; 浮點結果= a -b; | 浮點減法。 |
mul-loat | float a,b; 浮點結果= a * b; | 浮點乘法。 |
div-loat | float a,b; 浮點結果= a / b; | 浮點部門。 |
REM浮動 | float a,b; 浮點結果= a%b; | 劃分後剩餘的浮點。此函數與IEEE 754的剩餘不同,並定義為result == a - roundTowardZero(a / b) * b 。 |
加雙 | 雙a,b; 雙重結果= a + b; | 浮點增加。 |
子雙 | 雙a,b; 雙重結果= a -b; | 浮點減法。 |
穆爾雙 | 雙a,b; 雙重結果= a * b; | 浮點乘法。 |
Div-double | 雙a,b; 雙重結果= a / b; | 浮點部門。 |
rem-double | 雙a,b; 雙重結果= a%b; | 劃分後剩餘的浮點。此函數與IEEE 754的剩餘不同,並定義為result == a - roundTowardZero(a / b) * b 。 |