先日,そのsmaliファイルを読む機会があったので,そのときに学んだsmaliの文法をまとめておきます.
注意
- 説明の簡略化のために,メソッドとフィールドの説明におけるJavaのコードにおいて,文法を守っていない部分があります
- レジスタの説明などにおいて,一部smaliとdex,Dalvik VMを同一視しています
型
Javaにおける型は,基本データ型,クラス型,配列型の3種類に分けられます.それぞれの型について,smaliではどのように型を表記するかを示します.
- 基本データ型smaliでは,基本データ型は大文字のアルファベット1文字で表します.
smali Java V void Z boolean B byte S short C char I int L long F float D double
- クラス型
smaliでは,Javaと比較してクラス名の表記が以下の点で異なります. - クラス名の最初が"L"
- パッケージ名の区切り文字が"."ではなく"/"
- クラス名の最後が";"
例
smali | Java |
---|---|
Ljava/lang/Object; | java.lang.Object |
Ljava/lang/String; | java.lang.String |
Lpackage/name/ObjectName; | package.name.ObjectName |
- 配列型
smaliでは,配列型は"["から始まる文字列で表します.
例
smali | Java |
---|---|
[I | int[] |
[[I | int[][] |
[[[I | int[][][] |
[Ljava/lang/String; | java.lang.String[] |
メソッド
smaliでは,メソッドを以下のように表記します.
オブジェクト名->メソッド名(引数の型)戻り値の型例
smali |
---|
Lpackage/name/ObjectName;->MethodName(III)Z |
Java |
boolean package.name.ObjectName.MethodName(int, int, int) |
smali |
---|
Lpackage/name/ObjectName;->MethodName(I[[IILjava/lang/String;[Ljava/lang/Object;)Ljava/lang/String; |
Java |
String package.name.ObjectName.MethodName(int, int[][], int, String, Object[]) |
フィールド(メンバ変数)
smaliでは,フィールドを以下のように表記します.
オブジェクト名->フィールド名:フィールドの型
例
smali |
---|
Lpackage/name/ObjectName;->FieldName:Ljava/lang/String; |
Java |
String package.name.ObjectName.FieldName |
レジスタ
smaliでは,レジスタとよばれる変数を介して,引数の受け渡しなどを行っています.
ビット数
レジスタの大きさは32ビットで,boolean,intなどのほとんどの型を1つのレジスタに格納することができます.
ただし,long型,double型のみは,格納に64ビット必要なため,レジスタが2つ必要になります.
種類と表記
レジスタは,ローカルレジスタ,引数レジスタの2種類に分けられます.
ローカルレジスタはsmali上でv0,v1,v2…と表記され,レジスタの最大数は.localsディレクティブなどによって変動します.
たとえば".locals 5"であれば,v0~v4のレジスタを使用することができます.
引数レジスタはsmali上でp0,p1,p2…と表記されます.
レジスタの最大数や値は,staticメソッドかどうかによって,少し挙動が変わってきます.
レジスタの最大数や値は,staticメソッドかどうかによって,少し挙動が変わってきます.
- staticメソッドの場合
- 引数レジスタの最大数は(引数の数)個になります.
たとえば method(int, int, int, int) というメソッドであれば,引数の数は4個なので,p0~p3の4個のレジスタを使用することができます. - 引数レジスタは名前の通り,メソッドに渡された引数が格納されます.
たとえば method(1, 3, 5, 7) のようにメソッドを呼び出した場合,引数レジスタに格納される値はp0 = 1, p1 = 3, p2 = 5, p3 = 7になります. - staticメソッドでない場合
- 引数レジスタの最大数は(引数の数+1)個になります.
たとえば method(int, int, int, int) というメソッドであれば,引数の数は4個なので,p0~p4の5個のレジスタを使用することができます. - 引数レジスタは名前の通り,メソッドに渡された引数が格納されます.
ただし,staticメソッドでない場合は,p0にthisへの参照が格納されます.
たとえば method(1, 3, 5, 7) のようにメソッドを呼び出した場合,引数レジスタに格納される値はp0 = this, p1 = 1, p2 = 3, p3 = 5, p4 = 7になります.
なお,long型,double型はレジスタが2つ必要になるので,引数の数とレジスタの最大数がずれることに注意してください.
たとえばstaticメソッド method(long) の場合,引数は1個ですが,long型の格納にレジスタが2個必要になるため,レジスタの最大数は2個となり,第一引数はp0とp1に格納されます.
smaliの読み方
smaliの各行は大きく「コメント」「ラベル」「ディレクティブ」「命令」に分かれます.
「コメント」は,コンパイル時に無視される部分です.
Javaでは"//"以降がコメントになります.
smaliでは"#"以降がコメントになります.
「ラベル」はジャンプ命令などで飛ばされる先になります.
":"から始まる行がラベル行です.
":label1"のようにしてラベルを定義します.
「ディレクティブ」と「命令」の違いは気にしなくてもいいと思います.
文法的には"."から始まるものが「ディレクティブ」,そうでないものが「命令」となります.
内部的には,定数情報の格納を行うのが「ディレクティブ」,情報の操作などを行うのが「命令」という感じがします(あんまりよくわかってない).
命令一覧に関しては,Dalvik opcodesをご覧ください.
私が見たこと無いディレクティブはわからないので省略します….
「コメント」は,コンパイル時に無視される部分です.
Javaでは"//"以降がコメントになります.
smaliでは"#"以降がコメントになります.
「ラベル」はジャンプ命令などで飛ばされる先になります.
":"から始まる行がラベル行です.
":label1"のようにしてラベルを定義します.
「ディレクティブ」と「命令」の違いは気にしなくてもいいと思います.
文法的には"."から始まるものが「ディレクティブ」,そうでないものが「命令」となります.
内部的には,定数情報の格納を行うのが「ディレクティブ」,情報の操作などを行うのが「命令」という感じがします(あんまりよくわかってない).
命令一覧に関しては,Dalvik opcodesをご覧ください.
ディレクティブ一覧
私が見たこと無いディレクティブはわからないので省略します….
ディレクティブ | 説明 |
---|---|
.class | クラス名の定義 |
.class public Lpackage/name/ObjectName; | |
.super | スーパークラス |
.super Ljava/lang/Object; | |
.implements | 実装インターフェース |
.implements Ljava/io/Serializable; | |
.source | Javaソースファイル名 |
.source "ObjectName.java" | |
.field | フィールド定義 |
.field private FieldName:Ljava/lang/String; | |
.annotation | アノテーション |
.annotation runtime Lorg/junit/Test; .end annotation | |
.method | メソッド定義 |
.method public static main([Ljava/lang/String;)V メソッドの中身 .end method | |
.locals | ローカルレジスタ数の設定 |
.locals 5 #ローカル変数の個数は5個 | |
.array-data | 配列の初期値の定義 |
.array-data 4 #要素が4バイトの配列 0x800000 0x400000 0x200000 0x100000 .end array-data #設定された値はfill-array-data命令で書き込みできる | |
.packed-switch | 連続した値におけるswitch文の遷移先設定 |
.packed-switch 10 #値10から遷移チェックを開始 :label10 #値が10のときの遷移先ラベル :label11 #値が11のときの遷移先ラベル :label12 #値が12のときの遷移先ラベル :label13 #値が13のときの遷移先ラベル .end packed-switch #あくまで遷移先ラベルの設定のみで,実際の遷移は行われない #実際の遷移はpacked-switch命令で行われる | |
.sparse-switch | 飛び飛びの値におけるswitch文の遷移先設定 |
.sparse-switch 10 -> :label10 #値が10のときの遷移先ラベル 20 -> :label20 #値が20のときの遷移先ラベル 25 -> :label25 #値が25のときの遷移先ラベル 51 -> :label51 #値が51のときの遷移先ラベル .end sparse-switch #あくまで遷移先ラベルの設定のみで,実際の遷移は行われない #実際の遷移はsparse-switch命令で行われる | |
.line | Javaソースコードで何行目にあたるか(デバッグ用) |
.line 10 #Javaソースコードでは10行目 | |
.local | ローカル変数の個数 |
.line 10 #Javaソースコードでは10行目 |
Treasure Island Las Vegas Gentleman's Club 메리트 카지노 주소 메리트 카지노 주소 10cric login 10cric login 우리카지노 계열사 우리카지노 계열사 770NBA Betting Tips Over Under | Shootercasino
返信削除Welcome to the Jungle Casino - Jtmhub
返信削除Welcome to the Jungle Casino. It's 충주 출장샵 the newest casino 창원 출장마사지 in South Africa that has 제주 출장안마 become a cultural hub for 나주 출장안마 the gay 논산 출장안마 community. Since the beginning it has been accepting