Smali中.locals设为30,为何invoke-static使用v18报错?
Smali寄存器使用报错问题
我原本有一段运行正常的Smali代码,为了在Logcat中输出寄存器的值,我在move-result语句后添加了一行日志代码,具体代码如下:
.method public final onValidate(Landroidx/sqlite/db/SupportSQLiteDatabase;)Landroidx/room/RoomOpenHelper$ValidationResult; .locals 30 invoke-static {v9}, Lcom/mycompany/myapp/MyClass1;->getMystring(Ljava/lang/Object;)Ljava/lang/String; move-result-object v18 # 我添加的日志代码 invoke-static {v18}, Lcom/mycompany/myapp/MyClass2;->logMessage(Ljava/lang/String;)V
但现在出现了如下错误:
Invalid register: v18. Must be between v0 and v15, inclusive
明明.locals设置为30,为何我无法在invoke-static中使用v18?
原因与解决方法
核心原因
Smali语法对寄存器的命名有严格限制:
- 编号0-15的局部寄存器,可以用
v0-v15的格式表示; - 编号≥16的局部寄存器不能加
v前缀,必须直接写数字(比如16、18)。
你设置了.locals 30,说明方法拥有30个局部寄存器,编号范围是0-29,但v18这种写法违反了语法规则,因此触发报错。
修复代码
把所有v18的写法替换为18即可:
.method public final onValidate(Landroidx/sqlite/db/SupportSQLiteDatabase;)Landroidx/room/RoomOpenHelper$ValidationResult; .locals 30 invoke-static {v9}, Lcom/mycompany/myapp/MyClass1;->getMystring(Ljava/lang/Object;)Ljava/lang/String; move-result-object 18 # 修改后的日志调用 invoke-static {18}, Lcom/mycompany/myapp/MyClass2;->logMessage(Ljava/lang/String;)V
补充说明
对于方法参数寄存器:
- 非静态方法中,
p0代表当前对象(this),p1、p2...依次对应方法的参数; p0-p15是合法的命名格式,编号≥16的参数寄存器同样需要直接写数字,不能加p前缀。
内容的提问来源于stack exchange,提问作者mohsen
相关产品推荐
相关产品推荐

