You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 08:23:37