1

私はDalvikバイトコードのフォーマットに少し慣れていません。これらの*ベアリングレジスタが何を意味するのか疑問に思っています。たとえば、オブジェクトベアリング、例外ベアリングなどです。

同時に、生成されたバイトコードはレジスタではなくタイプを使用していますか?例えば、

throws Landroid/database/SQLExceptionが生成されますが、Landroid/database/SQLExceptionはタイプです。それでは、なぜ命令の要約に例外付きレジスタがどこにあるかが示されているthrow vAAのでしょうか。vAA私は何かが足りないのですか?

4

1 に答える 1

0

これは単に、命令が保持するデータのタイプを指します。vmは、その時点でレジスタにそのタイプのデータが含まれていることを静的に判別できる必要があります。つまり、すべての着信コードパスについて、そのレジスタはそのタイプのデータに設定されています。

レジスタタイプ情報がどのように伝播されるかをより詳細に調査したい場合は、-rオプションを使用して、baksmaliを使用してアプリケーションを逆コンパイルできます。これにより、各命令の前後に、関連するレジスタのレジスタタイプに関する情報を含むコメントが出力されます。その指示。この情報は、vmがバイトコードベリファイアで内部的に構築するレジスタタイプ情報と一致する必要があります。

たとえば、次のものを含むだけのメソッドがあるとします。

const-string v0, "Hello World!"
throw v0

これは許可されません。これは、throw命令の時点で、p0レジスタにThrowableから拡張されたオブジェクトへの参照が含まれていないためです(つまり、「例外を保持するレジスタ」ではありません)。

baksmaliで-rを使用すると、次のように表示されます。

#v0=(Uninit);
const-string v0, "Hello World!"
#v0=(Reference,Ljava/lang/String;);

#v0=(Reference,Ljava/lang/String;);
throw v0

これは、v0にthrow命令の時点で例外が含まれていないことを明確に示しています。

さらに、次のようなことは許可されません。

#v0=(Uninit);
new-instance v0, Ljava/lang/Exception;
#v0=(UninitRef,Ljava/lang/Exception;);

#v0=(UninitRef,Ljava/lang/Exception;);
invoke-direct {v0}, Ljava/lang/Exception;-><init>()V
#v0=(Reference,Ljava/lang/Exception;);

#p0=(Integer);
if-eqz p0, :cond_9

#v0=(Reference,Ljava/lang/Exception;);
const-string v0, "Hello World!"
#v0=(Reference,Ljava/lang/String;);

:cond_9
#v0=(Reference,Ljava/lang/Object;);
throw v0

スローの時点で、v0には例外または文字列が含まれている可能性があるためです。この場合、v0の「タイプ」はLjava/lang/Object;、両方のタイプの共通の親クラスであるため、として報告されます。

于 2012-05-04T22:06:31.003 に答える