我对Dalvik字节码的格式有点新,我很想知道这些* -bearing寄存器是什么意思,例如物体承载,异常承载等
同时,生成的字节码是使用类型,而不是寄存器?例如,
生成 throws Landroid/database/SQLException
,但Landroid/database/SQLException
是一种类型,那么为什么instruction summary说throw vAA
vAA
哪个是异常承载寄存器?
我错过了什么吗?
答案 0 :(得分:0)
这只是指指令所持有的数据类型。 vm必须能够静态地确定寄存器在该点包含该类型的数据。换句话说,对于所有传入的代码路径,该寄存器已被设置为该类型的数据。
如果您想更详细地研究寄存器类型信息的传播方式,可以使用-r选项使用b-malidi对应用程序进行反编译,该选项将在每条指令之前/之后输出注释,并提供有关寄存器寄存器类型的信息。与该指令相关。此信息应与字节码验证程序中内置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
因为在throw时,v0可能包含异常或字符串。在这种情况下,它将v0的“类型”报告为Ljava/lang/Object;
,因为这是两种类型的公共父类。