smali指令詳解
smali的資料型別
smali資料型別 | 資料型別 |
---|---|
B | byte |
C | char |
D | double |
F | float |
I | int |
J | long |
S | short |
V | void |
Z | boolean |
[XXX | array |
Lxxx/yyy | object |
這裡解析下最後兩項,陣列的表示方式是:在基本型別前加上前中括號“[”,例如int陣列和float陣列分別表示為:[I、[F;物件的表示則以L作為開頭,格式是LpackageName/objectName;(注意必須有個分號跟在最後),例如String物件在smali中為:Ljava/lang/String;,其中java/lang對應java.lang包,String就是定義在該包中的一個物件。
內部類:LpackageName/objectNamesubObjectName;。也就是在內部類前加“”符號。
函式的定義
Func-Name (Para-Type1Para-Type2Para-Type3…)Return-Type
注意引數與引數之間沒有任何分隔符,同樣舉幾個例子就容易明白了:
1. foo ()V void foo()。 2. foo (III)Z boolean foo(int, int, int)。 3. foo (Z[I[ILjava/lang/String;J)Ljava/lang/String; String foo (boolean, int[], int[], String, long) 4. foo ([Ljava/lang/String)Ljava/lang/String; String foo (String []) 5. foo(I[[IILjava/lang/String;[Ljava/lang/Object;)Ljava/lang/String; String method(int, int[][], int, String, Object[])
暫存器
對於一個使用m個暫存器(m=區域性變數暫存器個數l+引數暫存器個數n)的方法而言,區域性暫存器使用從v0開始的l個暫存器,而引數暫存器則使用最後的n個暫存器.舉個例子說明假設例項方法test(String a,String b)一共使用了5個暫存器:0,1,2,3,4,那麼引數暫存器是能使用2,3,4這三個暫存器,如圖
暫存器的命名
暫存器有兩種不同的命名方法:v字命名法和p字命 名法.這兩種命名法僅僅是影響了位元組碼的可讀性.
v字命名法
以小寫字母v開頭的方式表示方法中使用的區域性變數和引數.
對於上面例項方法test(String a,String b)來說,v0,v1為區域性變數能夠使用的暫存器,v2,v3,v4為引數能夠使用的暫存器:
p字命名法
以小寫字母p開頭的方式表示引數,引數名稱從p0開始,依次增大.區域性變數能夠使用的暫存器仍然是以v開頭.
總之不管是P還是V命名法,引數在後,區域性變數在前。
指令:
資料定義指令
資料定義指令用於定義程式碼中使用的常量,類等資料,基礎指令是const
指令 | 描述 |
---|---|
const/4 vA,#+B | 將數值符號擴充套件為32後賦值給暫存器vA |
const-wide/16 vAA,#+BBBB | 將數值符號擴充套件為64位後賦值個暫存器對vAA |
const-string vAA,[email protected] | 通過字串索引高走字串賦值給暫存器vAA |
const-class vAA,[email protected] | 通過型別索引獲取一個類的引用賦值給暫存器vAA |
資料操作指令
move指令用於資料操作,其表示move destination,source,即資料資料從source暫存器(源暫存器)移動到destionation暫存器(源暫存器),可以理解java中變數間的賦值操作.根據位元組碼和型別的不同,move指令後會跟上不同的字尾.
指令 | 描述 |
---|---|
move vA,vB | 將vB暫存器的值賦值給vA暫存器,vA和vB暫存器都是4位 |
move/from16 vAA,VBBBB | 將vBBBB暫存器(16位)的值賦值給vAA暫存器(7位),from16表示源暫存器vBBBB是16位的 |
move/16 vAAAA,vBBBB | 將暫存器vBBBB的值賦值給vAAAA暫存器,16表示源暫存器vBBBB和目標暫存器vAAAA都是16位 |
move-object vA,vB | 將vB暫存器中的物件引用賦值給vA暫存器,vA暫存器和vB暫存器都是4位 |
move-result vAA | 將上一個invoke指令(方法呼叫)操作的單字(32位)非物件結果賦值給vAA暫存器 |
move-result-wide vAA | 將上一個invoke指令操作的雙字(64位)非物件結果賦值給vAA暫存器 |
mvoe-result-object vAA | 將上一個invoke指令操作的物件結果賦值給vAA暫存器 |
move-exception vAA | 儲存上一個執行時發生的異常到vAA暫存器 |
物件操作指令
與物件例項相關的操作,比如物件建立,物件檢查等.
指令 | 描述 |
---|---|
new-instance vAA,[email protected] | 構造一個指定型別的物件將器引用賦值給vAA暫存器.此處不包含陣列物件 |
instance-of vA,vB,[email protected] | 判斷vB暫存器中物件的引用是否是指定型別,如果是,將v1賦值為1,否則賦值為0 |
check-cast vAA,[email protected] | 將vAA暫存器中物件的引用轉成指定型別,成功則將結果賦值給vAA,否則丟擲ClassCastException異常. |
陣列操作指令
在例項操作指令中我們並沒有發現建立物件的指令.Davilk中設定專門的指令用於陣列操作.
指令 | 描述 |
---|---|
new-array vA,vB,[email protected] | 建立指定型別與指定大小(vB暫存器指定)的陣列,並將其賦值給vA暫存器 |
fill-array-data vAA,+BBBBBBBB | 用指定的資料填充陣列,vAA代表陣列的引用(陣列的第一個元素的地址) |
資料運算指令
資料運算主要包括兩種:算數運算和邏輯運算.
算術運算指令
指令 | 描述 |
---|---|
add-type | 加法指令 |
sub-type | 減法指令 |
mul-type | 乘法指令 |
div-type | 除法指令 |
rem-type | 求 |
邏輯元算指令
指令 | 描述 |
---|---|
and-type | 與運算指令 |
or-type | 或運算指令 |
xor-type | 異或元算指令 |
位移指令
指令 | 描述 |
---|---|
shl-type | 有符號左移指令 |
shr-type | 有符號右移指令 |
ushr-type | 無符號右移指令 |
上面的-type表示操作的暫存器中資料的型別,可以是-int,-float,-long,-double等.
比較指令
比較指令用於比較兩個暫存器中值的大小,其基本格式格式是cmp+kind-type vAA,vBB,vCC,type表示比較資料的型別,如-long,-float等;kind則代表操作型別,因此有cmpl,cmpg,cmp三種比較指令.coml是compare less的縮寫,cmpg是compare greater的縮寫,因此cmpl表示vBB小於vCC中的值這個條件是否成立,是則返回1,否則返回-1,相等返回0;cmpg表示vBB大於vCC中的值這個條件是否成立,是則返回1,否則返回-1,相等返回0.
cmp和cmpg的語意一致,即表示vBB大於vCC暫存器中的值是否成立,成立則返回1,否則返回-1,相等返回0
來具體看看Davilk中的指令:
指令 | 描述 |
---|---|
cmpl-float vAA,vBB,vCC | 比較兩個單精度的浮點數.如果vBB暫存器中的值大於vCC暫存器的值,則返回-1到vAA中,相等則返回0,小於返回1 |
cmpg-float vAA,vBB,vCC | 比較兩個單精度的浮點數,如果vBB暫存器中的值大於vCC的值,則返回1,相等返回0,小於返回-1 |
cmpl-double vAA,vBB,vCC | 比較兩個雙精度浮點數,如果vBB暫存器中的值大於vCC的值,則返回-1,相等返回0,小於則返回1 |
cmpg-double vAA,vBB,vCC | 比較雙精度浮點數,和cmpl-float的語意一致 |
cmp-double vAA,vBB,vCC | 等價與cmpg-double vAA,vBB,vCC指令 |
欄位操作指令
欄位操作指令表示對物件欄位進行設值和取值操作,就像是你在程式碼中長些的set和get方法.基本指令是iput-type,iget-type,sput-type,sget-type.type表示資料型別普通欄位讀寫操作
字首是i的iput-type和iget-type指令用於欄位的讀寫操作.
指令 | 描述 |
---|---|
iget-byte vX,vY,filed_id | 讀取vY暫存器中的物件中的filed_id欄位值賦值給vX暫存器 |
iput-byte vX,vY,filed_id | 設定vY暫存器中的物件中filed_id欄位的值為vX暫存器的值 |
iget-boolean vX,vY,filed_id | |
iput-boolean vX,vY,filed_id | |
iget-long vX,vY,filed_id | |
iput-long vX,vY,filed_id |
靜態欄位讀寫操作
字首是s的sput-type和sget-type指令用於靜態欄位的讀寫操作
指令 | 描述 |
---|---|
sget-byte vX,vY,filed_id | |
sput-byte vX,vY,filed_id | |
sget-boolean vX,vY,filed_id | |
sput-boolean vX,vY,filed_id | |
sget-long vX,vY,filed_id | |
sput-long vX,vY,filed_id |
方法呼叫指令
Davilk中的方法指令和JVM的中指令大部分非常類似.目前共有五條指令集:
指令 | 描述 |
---|---|
invoke-direct{parameters},methodtocall | 呼叫例項的直接方法,即private修飾的方法.此時需要注意{}中的第一個元素代表的是當前例項物件,即this,後面接下來的才是真正的引數.比如指令invoke-virtual {v3,v1,v4},Test2.method5:(II)V中,v3表示Test2當前例項物件,而v1,v4才是方法引數 |
invoke-static{parameters},methodtocall | 呼叫例項的靜態方法,此時{}中的都是方法引數 |
invoke-super{parameters},methodtocall | 呼叫父類方法 |
invoke-virtual{parameters},methodtocall | 呼叫例項的虛方法,即public和protected修飾修飾的方法 |
invoke-interface{parameters},methodtocall | 呼叫介面方法 |
這五種指令是基本指令,除此之外,你也會遇到invoke-direct/range,invoke-static/range,invoke-super/range,invoke-virtual/range,invoke-interface/range指令,該型別指令和以上指令唯一的區別就是後者可以設定方法引數可以使用的暫存器的範圍,在引數多於四個時候使用.
再此強調一遍對於非靜態方法而言{}的結構是{當前例項物件,引數1,引數2,…引數n},而對於靜態方法而言則是{引數1,引數2,…引數n}
需要注意,如果要獲取方法執行有返回值,需要通過上面說道的move-result指令獲取執行結果.
方法返回指令
在java中,很多情況下我們需要通過Return返回方法的執行結果,在Davilk中同樣提供的return指令來返回執行結果:
指令 | 描述 |
---|---|
return-void | 什麼也不返回 |
return vAA | 返回一個32位非物件型別的值 |
return-wide vAA | 返回一個64位非物件型別的值 |
return-object vAA | 反會一個物件型別的引用 |
同步指令
同步一段指令序列通常是由java中的synchronized語句塊表示,則JVM中是通過monitorenter和monitorexit的指令來支援synchronized關鍵字的語義的,而在Davilk中同樣提供了兩條類似的指令來支援synchronized語義:
指令 | 描述 |
---|---|
monitor-enter vAA | 為指定物件獲取鎖操作 |
monitor-exit vAA | 為指定物件釋放鎖操作 |
異常指令
很久以前,VM也是用過jsr和ret指令來實現異常的,但是現在的JVM中已經丟擲原先的做法,轉而採用異常表來實現異常.而Davilk仍然使用指令來實現:
指令 | 描述 |
---|---|
throw vAA | 丟擲vAA暫存器中指定型別的異常 |
跳轉指令
跳轉指令用於從當前地址條狀到指定的偏移處,在if,switch分支中使用的居多.Davilk中提供了goto,packed-switch,if-test指令用於實現跳轉操作
指令 | 描述 |
---|---|
goto +AA | 無條件跳轉到指定偏移處(AA即偏移量) |
packed-switch vAA,+BBBBBBBB | 分支跳轉指令.vAA暫存器中的值是switch分支中需要判斷的,BBBBBBBB則是偏移表(packed-switch-payload)中的索引值, |
spare-switch vAA,+BBBBBBBB | 分支跳轉指令,和packed-switch類似,只不過BBBBBBBB偏移表(spare-switch-payload)中的索引值 |
if-test vA,vB,+CCCC | 條件跳轉指令,用於比較vA和vB暫存器中的值,如果條件滿足則跳轉到指定偏移處(CCCC即偏移量),test代表比較規則,可以是eq.lt等. |
在條件比較中,if-test中的test表示比較規則.該指令用的非常多,因此我們簡單的坐下說明:
指令 | 描述 |
---|---|
if-eq vA,vB,target | vA,vB暫存器中的相等,等價於java中的if(a==b),比如if-eq v3,v10,002c表示如果條件成立,則跳轉到current position+002c處.其餘的類似 |
if-ne vA,vB,target | 等價與java中的if(a!=b) |
if-lt vA,vB,target | vA暫存器中的值小於vB,等價於if(a>=b) |
if-gt vA,vB,target | 等價於java中的if(a>b) |
if-ge vA,vB,target | 等價於java中的if(a>=b) |
if-le vA,vB,target | 等價於java中的if(a<=b) |
除了以上指令之外,Davilk還提供可一個零值條件指令,該指令用於和0比較,可以理解為將上面指令中的vB暫存器的值固定為0.
指令 | 描述 |
---|---|
if-eqz vAA,target | 等價於java中的if(a==0)或者if(!a) |
if-nez vAA,target | 等價於java中的if(a!=0)或者if(a) |
if-ltz vAA,target | 等價於java中的if(a<0) |
if-gtz vAA,target | 等價於java中的if(a>0) |
if-lez vAA,target | 等價於java中的if(a<=0) |
if-gtz vAA,target | 等價於java中的if(a>=0) |
上面我們說道兩張偏移表packed-switch-payload和spare-switch-payload,兩者唯一的區別就是表中的值是否有序,後面我們會在下文中進行詳細的說明.
資料轉換指令
資料型別轉換對任何java開發者都是非常熟悉的,用於實現兩種不同資料型別的相互轉換.其基本指令格式是:unop vA,vB,表示對vB暫存器的中值進行操作,並將結果儲存在vA暫存器中.
指令 | 描述 |
---|---|
int-to-long | 整形轉為長整型 |
float-to-int | 單精度浮點型轉為整形 |
int-to-byte | 整形轉為位元組型別 |
neg-int | 求補指令,對整數求補 |
not-int | 求反指令,對整數求反 |
結合下表的指令大全:
Opcode (hex) | Opcode name | Explanation | Example |
00 | nop | No operation | 0000 - nop |
01 | move vx,vy | Moves the content of vy into vx. Both registers must be in the first 256 register range. | 0110 - move v0, v1 Moves v1 into v0. |
02 | move/from16 vx,vy | Moves the content of vy into vx. vy may be in the 64k register range while vx is one of the first 256 registers. | 0200 1900 - move/from16 v0, v25 Moves v25 into v0. |
03 | move/16 | ||
04 | move-wide | ||
05 | move-wide/from16 vx,vy | Moves a long/double value from vy to vx. vy may be in the 64k register range while wx is one of the first 256 registers. | 0516 0000 - move-wide/from16 v22, v0 Moves v0 into v22. |
06 | move-wide/16 | ||
07 | move-object vx,vy | Moves the object reference from vy to vx. | 0781 - move-object v1, v8 Moves the object reference in v8 to v1. |
08 | move-object/from16 vx,vy | Moves the object reference from vy to vx, vy can address 64k registers and vx can address 256 registers. | 0801 1500 - move-object/from16 v1, v21 Move the object reference in v21 to v1. |
09 | move-object/16 | ||
0A | move-result vx | Move the result value of the previous method invocation into vx. | 0A00 - move-result v0 Move the return value of a previous method invocation into v0. |
0B | move-result-wide vx | Move the long/double result value of the previous method invocation into vx,vx+1. | 0B02 - move-result-wide v2 Move the long/double result value of the previous method invocation into v2,v3. |
0C | move-result-object vx | Move the result object reference of the previous method invocation into vx. | 0C00 - move-result-object v0 |
0D | move-exception vx | Move the exception object reference thrown during a method invocation into vx. | 0D19 - move-exception v25 |
0E | return-void | Return without a return value | 0E00 - return-void |
0F | return vx | Return with vx return value | 0F00 - return v0 Returns with return value in v0. |
10 | return-wide vx | Return with double/long result in vx,vx+1. | 1000 - return-wide v0 Returns with a double/long value in v0,v1. |
11 | return-object vx | Return with vx object reference value. | 1100 - return-object v0 Returns with object reference value in v0 |
12 | const/4 vx,lit4 | Puts the 4 bit constant into vx | 1221 - const/4 v1, #int2 Moves literal 2 into v1. The destination register is in the lower 4 bit in the second byte, the literal 2 is in the higher 4 bit. |
13 | const/16 vx,lit16 | Puts the 16 bit constant into vx | 1300 0A00 - const/16 v0, #int 10 Puts the literal constant of 10 into v0. |
14 | const vx, lit32 | Puts the integer constant into vx | 1400 4E61 BC00 - const v0, #12345678 // #00BC614E Moves literal 12345678 into v0. |
15 | const/high16 v0, lit16 | Puts the 16 bit constant into the topmost bits of the register. Used to initialize float values. | 1500 2041 - const/high16 v0, #float 10.0 // #41200000 Moves the floating literal of 10.0 into v0. The 16 bit literal in the instruction carries the top 16 bits of the floating point number. |
16 | const-wide/16 vx, lit16 | Puts the integer constant into vx and vx+1 registers, expanding the integer constant into a long constant.. | 1600 0A00 - const-wide/16 v0, #long 10 Moves literal 10 into v0 and v1 registers. |
17 | const-wide/32 vx, lit32 | Puts the 32 bit constant into vx and vx+1 registers, expanding the integer constant into a long constant. | 1702 4e61 bc00 - const-wide/32 v2, #long 12345678 // #00bc614e Puts #12345678 into v2 and v3 registers. |
18 | const-wide vx, lit64 | Puts the 64 bit constant into vx and vx+1 registers. | 1802 874b 6b5d 54dc 2b00- const-wide v2, #long 12345678901234567 // #002bdc545d6b4b87 Puts #12345678901234567 into v2 and v3 registers. |
19 | const-wide/high16 vx,lit16 | Puts the 16 bit constant into the highest 16 bit of vx and vx+1 registers. Used to initialize double values. | 1900 2440 - const-wide/high16 v0, #double 10.0 // #402400000 Puts the double constant of 10.0 into v0 register. |
1A | const-string vx,string_id | Puts reference to a string constant identified by string_id into vx. | 1A08 0000 - const-string v8, “” // [email protected] Puts reference to [email protected] (entry #0 in the string table) into v8. |
1B | const-string-jumbo | ||
1C | const-class vx,type_id | Moves the class object of a class identified by type_id (e.g. Object.class) into vx. | 1C00 0100 - const-class v0, Test3 // [email protected] Moves reference to Test3.class (entry#1 in the type id table) into |
1D | monitor-enter vx | Obtains the monitor of the object referenced by vx. | 1D03 - monitor-enter v3 Obtains the monitor of the object referenced by v3. |
1E | monitor-exit | Releases the monitor of the object referenced by vx. | 1E03 - monitor-exit v3 Releases the monitor of the object referenced by v3. |
1F | check-cast vx, type_id | Checks whether the object reference in vx can be cast to an instance of a class referenced by type_id. Throws ClassCastException if the cast is not possible, continues execution otherwise. | 1F04 0100 - check-cast v4, Test3 // [email protected] Checks whether the object reference in v4 can be cast to [email protected] (entry #1 in the type id table) |
20 | instance-of vx,vy,type_id | Checks whether vy is instance of a class identified by type_id. Sets vx non-zero if it is, 0 otherwise. | 2040 0100 - instance-of v0, v4, Test3 // [email protected] Checks whether the object reference in v4 is an instance of [email protected] (entry #1 in the type id table). Sets v0 to non-zero if v4 is instance of Test3, 0 otherwise. |
21 | array-length vx,vy | Calculates the number of elements of the array referenced by vy and puts the length value into vx. | 2111 - array-length v1, v1 Calculates the number of elements of the array referenced by v1 and puts the result into v1. |
22 | new-instance vx,type | Instantiates an object type and puts the reference of the newly created instance into vx. | 2200 1500 - new-instance v0, java.io.FileInputStream // [email protected]015 Instantiates [email protected] (entry #15H in the type table) and puts its reference into v0. |
23 | new-array vx,vy,type_id | Generates a new array of type_id type and vy element size and puts the reference to the array into vx. | 2312 2500 - new-array v2, v1, char[] // [email protected] Generates a new array of [email protected] type and v1 size and puts the reference to the new array into v2. |
24 | filled-new-array {parameters},type_id | Generates a new array of type_id and fills it with the parameters5. Reference to the newly generated array can be obtained by a move-result-object instruction, immediately following the filled-new-array instruction. | 2420 530D 0000 - filled-new-array {v0,v0},[I // [email protected] Generates a new array of [email protected] The array’s size will be 2 and both elements will be filled with the contents of v0 register. |
25 | filled-new-array-range {vx..vy},type_id | Generates a new array of type_id and fills it with a range of parameters. Reference to the newly generated array can be obtained by a move-result-object instruction, immediately following the filled-new-array instruction. | 2503 0600 1300 - filled-new-array/range {v19..v21}, [B // [email protected] Generates a new array of [email protected] The array’s size will be 3 and the elements will be filled using the v19,v20 and v21 registers4. |
26 | fill-array-data vx,array_data_offset | Fills the array referenced by vx with the static data. The location of the static data is the sum of the position of the current instruction and the offset | 2606 2500 0000 - fill-array-data v6, 00e6 // +0025 Fills the array referenced by v0 with the static data at current instruction+25H words location. The offset is expressed as a 32-bit number. The static data is stored in the following format: 0003 // Table type: static array data 0400 // Byte per array element (in this case, 4 byte integers) 0300 0000 // Number of elements in the table 0100 0000 // Element #0: integer 1 0200 0000 // Element #1: integer 2 0300 0000 // Element #2: integer3 |
27 | throw vx | Throws an exception object. The reference of the exception object is in vx. | 2700 - throw v0 Throws an exception. The exception object reference is in v0. |
28 | goto target | Unconditional jump by short offset2. | 28F0 - goto 0005 // -0010 Jumps to current position-16 words (hex 10). 0005 is the label of the target instruction. |
29 | goto/16 target | Unconditional jump by 16 bit offset2. | 2900 0FFE - goto/16 002f // -01f1 Jumps to the current position-1F1H words. 002F is the label of the target instruction. |
2A | goto/32 target | ||
2B | packed-switch vx,table | Implements a switch statement where the case constants are close to each other. The instruction uses an index table. vx indexes into this table to find the offset of the instruction for a particular case. If vx falls out of the index table, the execution continues on the next instruction (default case). | 2B02 0C00 0000 - packed-switch v2, 000c // +000c Execute a packed switch according to the switch argument in v2. The position of the index table is at current instruction+0CH words. The table looks like the following: 0001 // Table type: packed switch table 0300 // number of elements 0000 0000 // element base 0500 0000 0: 00000005 // case 0: +00000005 0700 0000 1: 00000007 // case 1: +00000007 0900 0000 2: 00000009 // case 2: +00000009 |
2C | sparse-switch vx,table | Implements a switch statement with sparse case table. The instruction uses a lookup table with case constants and offsets for each case constant. If there is no match in the table, execution continues on the next instruction (default case). | 2C02 0c00 0000 - sparse-switch v2, 000c // +000c Execute a sparse switch according to the switch argument in v2. The position of the lookup table is at current instruction+0CH words. The table looks like the following. 0002 // Table type: sparse switch table 0300 // number of elements 9cff ffff // first case: -100 fa00 0000 // second case constant: 250 e803 0000 // third case constant: 1000 0500 0000 // offset for the first case constant: +5 0700 0000 // offset for the second case constant: +7 0900 0000 // offset for the third case constant: +9 |
2D | cmpl-float | Compares the float values in vy and vz and sets the integer value in vx accordingly3 | 2D00 0607 - cmpl-float v0, v6, v7 Compares the float values in v6 and v7 then sets v0 accordingly. NaN bias is less-than, the instruction will return -1 if any of the parameters is NaN. |
2E | cmpg-float vx, vy, vz | Compares the float values in vy and vz and sets the integer value in vx accordingly3. | 2E00 0607 - cmpg-float v0, v6, v7 Compares the float values in v6 and v7 then sets v0 accordingly. NaN bias is greater-than, the instruction will return 1 if any of the parameters is NaN. |
2F | cmpl-double vx,vy,vz | Compares the double values in vy and vz2 and sets the integer value in vx accordingly3. | 2F19 0608 - cmpl-double v25, v6, v8 Compares the double values in v6,v7 and v8,v9 and sets v25 accordingly. NaN bias is less-than, the instruction will return -1 if any of the parameters is NaN. |
30 | cmpg-double vx, vy, vz | Compares the double values in vy and vz2 and sets the integer value in vx accordingly3. | 3000 080A - cmpg-double v0, v8, v10 Compares the double values in v8,v9 and v10,v11 then sets v0 accordingly. NaN bias is greater-than, the instruction will return 1 if any of the parameters is NaN. |
31 | cmp-long vx, vy, vz | Compares the long values in vy and vz and sets the integer value in vx accordingly3. | 3100 0204 - cmp-long v0, v2, v4 Compares the long values in v2 and v4 then sets v0 accordingly. |
32 | if-eq vx,vy,target | Jumps to target if vx==vy2. vx and vy are integer values. | 32b3 6600 - if-eq v3, v11, 0080 // +0066 Jumps to the current position+66H words if v3==v11. 0080 is the label of the target instruction. |
33 | if-ne vx,vy,target | Jumps to target if vx!=vy2. vx and vy are integer values. | 33A3 1000 - if-ne v3, v10, 002c // +0010 Jumps to the current position+10H words if v3!=v10. 002c is the label of the target instruction. |
34 | if-lt vx,vy,target | Jumps to target is vx<vy2. vx and vy are integer values. | 3432 CBFF - if-lt v2, v3, 0023 // -0035 Jumps to the current position-35H words if v2<v3. 0023 is the label of the target instruction. |
35 | if-ge vx, vy,target | Jumps to target if vx>=vy2. vx and vy are integer values. | 3510 1B00 - if-ge v0, v1, 002b // +001b Jumps to the current position+1BH words if v0>=v1. 002b is the label of the target instruction. |
36 | if-gt vx,vy,target | Jumps to target if vx>vy2. vx and vy are integer values. | 3610 1B00 - if-ge v0, v1, 002b // +001b Jumps to the current position+1BH words if v0>v1. 002b is the label of the target instruction. |
37 | if-le vx,vy,target | Jumps to target if vx<=vy2. vx and vy are integer values. | 3756 0B00 - if-le v6, v5, 0144 // +000b Jumps to the current position+0BH words if v6<=v5. 0144 is the label of the target instruction. |
38 | if-eqz vx,target | Jumps to target if vx==02. vx is an integer value. | 3802 1900 - if-eqz v2, 0038 // +0019 Jumps to the current position+19H words if v2==0. 0038 is the label of the target instruction. |
39 | if-nez vx,target | Checks vx and jumps if vx is nonzero2. | 3902 1200 - if-nez v2, 0014 // +0012 Jumps to current position+18 words (hex 12) if v2 is nonzero. 0014 is the label of the target instruction. |
3A | if-ltz vx,target | Checks vx and jumps if vx<02. | 3A00 1600 - if-ltz v0, 002d // +0016 Jumps to the current position+16H words if v0<0. 002d is the label of the target instruction. |
3B | if-gez vx,target | Checks vx and jumps if vx>=02. | 3B00 1600 - if-gez v0, 002d // +0016 Jumps to the current position+16H words if v0 >=0. 002d is the label of the target instruction. |
3C | if-gtz vx,target | Checks vx and jumps if vx>02. | 3C00 1D00 - if-gtz v0, 004a // +001d Jumps to the current position+1DH words if v0>0. 004A is the label of the target instruction. |
3D | if-lez vx,target | Checks vx and jumps if vx<=02. | 3D00 1D00 - if-lez v0, 004a // +001d Jumps to the current position+1DH words if v0<=0. 004A is the label of the target instruction. |
3E | unused_3E | ||
3F | unused_3F | ||
40 | unused_40 | ||
41 | unused_41 | ||
42 | unused_42 | ||
43 | unused_43 | ||
44 | aget vx,vy,vz | Gets an integer value of an object reference array into vx. The array is referenced by vy and is indexed by vz. | 4407 0306 - aget v7, v3, v6 Gets an integer array element. The array is referenced by v3 and the element is indexed by v6. The element will be put into v7. |
45 | aget-wide vx,vy,vz | Gets a long/double value of long/double array into vx,vx+1. The array is referenced by vy and is indexed by vz. | 4505 0104 - aget-wide v5, v1, v4 Gets a long/double array element. The array is referenced by v1 and the element is indexed by v4. The element will be put into v5,v6. |
46 | aget-object vx,vy,vz | Gets an object reference value of an object reference array into vx. The array is referenced by vy and is indexed by vz. | 4602 0200 - aget-object v2, v2, v0 Gets an object reference array element. The array is referenced by v2 and the element is indexed by v0. The element will be put into v2. |
47 | aget-boolean vx,vy,vz | Gets a boolean value of a boolean array into vx. The array is referenced by vy and is indexed by vz. | 4700 0001 - aget-boolean v0, v0, v1 Gets a boolean array element. The array is referenced by v0 and the element is indexed by v1. The element will be put into v0. |
48 | aget-byte vx,vy,vz | Gets a byte value of a byte array into vx. The array is referenced by vy and is indexed by vz. | 4800 0001 - aget-byte v0, v0, v1 Gets a byte array element. The array is referenced by v0 and the element is indexed by v1. The element will be put into v0. |
49 | aget-char vx, vy,vz | Gets a char value of a character array into vx. The element is indexed by vz, the array object is referenced by vy | 4905 0003 - aget-char v5, v0, v3 Gets a character array element. The array is referenced by v0 and the element is indexed by v3. The element will be put into v5. |
4A | aget-short vx,vy,vz | Gets a short value of a short array into vx. The element is indexed by vz, the array object is referenced by vy. | 4A00 0001 - aget-short v0, v0, v1 Gets a short array element. The array is referenced by v0 and the element is indexed by v1. The element will be put into v0. |
4B | aput vx,vy,vz | Puts the integer value in vx into an element of an integer array. The element is indexed by vz, the array object is referenced by vy. | 4B00 0305 - aput v0, v3, v5 Puts the integer value in v2 into an integer array referenced by v0. The target array element is indexed by v1. |
4C | aput-wide vx,vy,vz | Puts the double/long value in vx,vx+1 into a double/long array. The array is referenced by vy, the element is indexed by vz. | 4C05 0104 - aput-wide v5, v1, v4 Puts the double/long value in v5,v6 into a double/long array referenced by v1. The target array element is indexed by v4. |
4D | aput-object vx,vy,vz | Puts the object reference value in vx into an element of an object reference array. The element is indexed by vz, the array object is referenced by vy. | 4D02 0100 - aput-object v2, v1, v0 Puts the object reference value in v2 into an object reference array referenced by v0. The target array element is indexed by v1. |
4E | aput-boolean vx,vy,vz | Puts the boolean value in vx into an element of a boolean array. The element is indexed by vz, the array object is referenced by vy. | 4E01 0002 - aput-boolean v1, v0, v2 Puts the boolean value in v1 into an object reference array referenced by v0. The target array element is indexed by v2. |
4F | aput-byte vx,vy,vz | Puts the byte value in vx into an element of a byte array. The element is indexed by vz, the array object is referenced by vy. | 4F02 0001 - aput-byte v2, v0, v1 Puts the boolean value in v2 into a byte array referenced by v0. The target array element is indexed by v1. |
50 | aput-char vx,vy,vz | Puts the char value in vx into an element of a character array. The element is indexed by vz, the array object is referenced by vy. | 5003 0001 - aput-char v3, v0, v1 Puts the character value in v3 into a character array referenced by v0. The target array element is indexed by v1. |
51 | aput-short vx,vy,vz | Puts the short value in vx into an element of a short array. The element is indexed by vz, the array object is referenced by vy. | 5102 0001 - aput-short v2, v0, v1 Puts the short value in v2 into a character array referenced by v0. The target array element is indexed by v1. |
52 | iget vx, vy, field_id | Reads an instance field into vx. The instance is referenced by vy. | 5210 0300 - iget v0, v1, Test2.i6:I // [email protected] Reads [email protected] into v0 (entry #3 in the field id table). The instance is referenced by v1. |
53 | iget-wide vx,vy,field_id | Reads an instance field into vx1. The instance is referenced by vy. | 5320 0400 - iget-wide v0, v2, Test2.l0:J // [email protected] Reads [email protected] into v0 and v1 registers (entry #4 in the field id table). The instance is referenced by v2. |
54 | iget-object vx,vy,field_id | Reads an object reference instance field into vx. The instance is referenced by vy. | iget-object v1, v2, LineReader.fis:Ljava/io/FileInputStream; // [email protected] Reads [email protected] into v1 (entry #2 in the field id table). The instance is referenced by v2. |
55 | iget-boolean vx,vy,field_id | Reads a boolean instance field into vx. The instance is referenced by vy. | 55FC 0000 - iget-boolean v12, v15, Test2.b0:Z // [email protected] Reads the boolean [email protected] into v12 register (entry #0 in the field id table). The instance is referenced by v15. |
56 | iget-byte vx,vy,field_id | Reads a byte instance field into vx. The instance is referenced by vy. | 5632 0100 - iget-byte v2, v3, Test3.bi1:B // [email protected] Reads the char [email protected] into v2 register (entry #1 in the field id table). The instance is referenced by v3. |
57 | iget-char vx,vy,field_id | Reads a char instance field into vx. The instance is referenced by vy. | 5720 0300 - iget-char v0, v2, Test3.ci1:C // [email protected] Reads the char [email protected] into v0 register (entry #3 in the field id table). The instance is referenced by v2. |
58 | iget-short vx,vy,field_id | Reads a short instance field into vx. The instance is referenced by vy. | 5830 0800 - iget-short v0, v3, Test3.si1:S // [email protected] Reads the short [email protected] into v0 register (entry #8 in the field id table). The instance is referenced by v3. |
59 | iput vx,vy, field_id | Puts vx into an instance field. The instance is referenced by vy. | 5920 0200 - iput v0,v2, Test2.i6:I // [email protected] Stores v0 into [email protected] (entry #2 in the field id table). The instance is referenced by v2. |
5A | iput-wide vx,vy, field_id | Puts the wide value located in vx and vx+1 registers into an instance field. The instance is referenced by vy. | 5A20 0000 - iput-wide v0,v2, Test2.d0:D // [email protected] Stores the wide value in v0, v1 registers into [email protected] (entry #0 in the field id table). The instance is referenced by v2. |
5B | iput-object vx,vy,field_id | Puts the object reference in vx into an instance field. The instance is referenced by vy. | 5B20 0000 - iput-object v0, v2, LineReader.bis:Ljava/io/BufferedInputStream; // [email protected] Stores the object reference in v0 into [email protected] (entry #0 in the field table). The instance is referenced by v2. |
5C | iput-boolean vx,vy, field_id | Puts the boolean value located in vx into an instance field. The instance is referenced by vy. | 5C30 0000 - iput-boolean v0, v3, Test2.b0:Z // [email protected] Puts the boolean value in v0 into [email protected] (entry #0 in the field id table). The instance is referenced by v3. |
5D | iput-byte vx,vy,field_id | Puts the byte value located in vx into an instance field. The instance is referenced by vy. | 5D20 0100 - iput-byte v0, v2, Test3.bi1:B // [email protected] Puts the boolean value in v0 into [email protected] (entry #1 in the field id table). The instance is referenced by v2. |
5E | iput-char vx,vy,field_id | Puts the char value located in vx into an instance field. The instance is referenced by vy. | 5E20 0300 - iput-char v0, v2, Test3.ci1:C // [email protected] Puts the char value in v0 into [email protected] (entry #3 in the field id table). The instance is referenced by v2. |
5F | iput-short vx,vy,field_id | Puts the short value located in vx into an instance field. The instance is referenced by vy. | 5F21 0800 - iput-short v1, v2, Test3.si1:S // [email protected] Puts the short value in v1 into [email protected] (entry #8 in the field id table). The instance is referenced by v2. |
60 | sget vx,field_id | Reads the integer field identified by the field_id into vx. | 6000 0700 - sget v0, Test3.is1:I // [email protected] Reads [email protected] (entry #7 in the field id table) into v0. |
61 | sget-wide vx, field_id | Reads the static field identified by the field_id into vx and vx+1 registers. | 6100 0500 - sget-wide v0, Test2.l1:J // [email protected] Reads [email protected] (entry #5 in the field id table) into v0 and v1 registers. |
62 | sget-object vx,field_id | Reads the object reference field identified by the field_id into vx. | 6201 0C00 - sget-object v1, Test3.os1:Ljava/lang/Object; // [email protected] Reads [email protected] (entry #CH in the field id table) into v1. |
63 | sget-boolean vx,field_id | Reads the boolean static field identified by the field_id into vx. | 6300 0C00 - sget-boolean v0, Test2.sb:Z // [email protected] Reads boolean [email protected] (entry #12 in the field id table) into v0. |
64 | sget-byte vx,field_id | Reads the byte static field identified by the field_id into vx. | 6400 0200 - sget-byte v0, Test3.bs1:B // [email protected] Reads byte [email protected] (entry #2 in the field id table) into v0. |
65 | sget-char vx,field_id | Reads the char static field identified by the field_id into vx. | 6500 0700 - sget-char v0, Test3.cs1:C // [email protected] Reads byte [email protected] (entry #7 in the field id table) into v0. |
66 | sget-short vx,field_id | Reads the short static field identified by the field_id into vx. | 6600 0B00 - sget-short v0, Test3.ss1:S // [email protected] Reads short |