Dalvik的字节码主要有两种类型,原始类型和引用类型。引用类型包括对象和数组,除了引用类型其它的都是原始类型。
原始类型会单独用一张表表示。表格中的缩写它们实际存在dex文件中。在 dex-format.html文档中有定义 (dalvik/docs/dex/format.html in the AOSP repository)。
一、Smali数据类型
下面的表格是Java数据类型与Smali汇编数据类型的对应关系:
Smali数据类型 | Java数据类型 |
V | void -仅仅用于返回值 |
Z | boolean |
B | byte |
S | short |
C | char |
I | int |
J | long (64 bits) |
F | float |
D | double (64位) |
引用类型:包括对象类型和数组类型
对象类型表示方式:Lpackage/name/ObjectName;
L表示它是一个对象,package/name/对象所在的包名,ObjectName是对象名,以分号结尾;这个与Java中的package.name.ObjectName是等价的.例如,Ljava/lang/String;等价于java.lang.String。
例如:Ljava/lang/String 表示java.lang包名下的String类型
数组类型表示方式:一维数组:[类型。二维数组:[[类型。几维数组就有几个[,后面跟上原始数据类型或者对象类型即可。最多可表示255维数组。
例如:
[Z 表示一维布尔类型数组,与java中的 boolean[] 等价
[B 表示一维字节类型的数组,与java中的byte[]等价
[S 表示一维短整型类型的数组,与java中的byte[]等价
[C 表示一维字符型数组,与java中的char[]等价
[I 表示一维整型数组,与java中的int[]等价
[J 表示一维长整型数组,与java中的long[]等价
[F 表示一维浮点型数组,与java中的float[]等价
[D 表示一维双精度浮点型数组,与java中的double[]等价
[Ljava/lang/String 等价于Java中的String[]
二、Smali函数方法的语法:
Lpackage/name/ObjectName;->MethodName(参数类型)Z
函数包括函数名,参数类型和返回值类型. 虚拟机需要这些信息找到正确的方法。
例子如下:
Lpackage/name/ObjectName;->MethodName(III)Z这个例子中, 你可以识别 Lpackage/name/ObjectName; MethodName 明显的是方法名. (III)Z是方法的签名 . III是参数 (在这个例子中表示三个整型), Z 表示返回值为boolean类型. 方法参数中间没有分隔符 。
下面是一些更复杂的例子:
method(I[[IILjava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;
在java中表示如下:
String method(int, int[][], int, String, Object[])
三、Smali字段语法:
Lpackage/name/ObjectName;->FieldName:Ljava/lang/String;
四、Smali汇编指令,一个寄存器32位
操作码 | 操作码名称 | 解释说明 | 例子 |
00 | nop | 无操作 | 0000 - nop |
01 | move vx,vy | vy的内容给vx | 0110 - move v0, v1 v1值给v0. |
02 | move/from16 vx,vy | vy的内容给vx. vy ,vy范围是v0-v65535,vx是v0-v255 | move/from16 v255,v60000 |
03 | move/16 | ||
04 | move-wide | ||
05 | move-wide/from16 vx,vy | vy的long/double类型的值给 vx. vy 的范围是0-2^16.vx是前256个寄存器. | 0516 0000 - move-wide/from16 v22, v0 Moves v0 into v22. |
06 | move-wide/16 | ||
07 | move-object vx,vy | vy中的对象引用给vx. | 0781 - move-object v1, v8 Moves the object reference in v8 to v1. |
08 | move-object/from16 vx,vy | vy中的对象引用给vx, vy范围是v0-v65535,vx是v0-v255 | 0801 1500 - move-object/from16 v1, v21 Move the object reference in v21 to v1. |
09 | move-object/16 | ||
0A | move-result vx | 先前调用函数的返回值给vx | 0A00 - move-result v0 Move the return value of a previous method invocation into v0. |
0B | move-result-wide vx | 函数返回的 long/double结果值给 vx,vx+1。因为结果是64位需要两个32位存储 | 0B02 - move-result-wide v2 Move the long/double result value of the previous method invocation into v2,v3. |
0C | move-result-object vx | 先前函数的返回值的引用给vx. | 0C00 - move-result-object v0 |