其他分享
首页 > 其他分享> > Smali 语法解析,面试必备

Smali 语法解析,面试必备

作者:互联网

我们首先看一下生成的 Hello.smali 文件内容:

.class public LHello;
.super Ljava/lang/Object;
.source "Hello.java"

# static fields
.field private static HELLO_WORLD:Ljava/lang/String;

# direct methods
.method static constructor <clinit>()V
    .registers 1

    .prologue
    .line 3
    const-string v0, "Hello World!"

    sput-object v0, LHello;->HELLO_WORLD:Ljava/lang/String;

    return-void
.end method

.method public constructor <init>()V
    .registers 1

    .prologue
    .line 1
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    return-void
.end method

.method public static main([Ljava/lang/String;)V
    .registers 3

    .prologue
    .line 6
    sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;

    sget-object v1, LHello;->HELLO_WORLD:Ljava/lang/String;

    invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

    .line 7
    return-void
.end method 

文件头

首先看一下文件头部分:

.class public LHello;       // 类名
.super Ljava/lang/Object;   // 父类名
.source "Hello.java"        // 源文件名称 

.class 后面是 访问修饰符和当前类,这里类名用 LHello 表示。那么这个 L 代表什么呢?其实之前的 Class 文件中也出现过这种表示方法,JVM 的字节码指令和 Dalvik 的字节码指令有很多地方都是类似的。Java 中分为基本类型和引用类型,DalviK 对这两种类型分别有不同的描述方法。对于基本类型和 Void 类型,都是用一个大写字母表示。对于引用类型,使用字母 L 加上对象类型的全限定名来表示。具体规则如下表所示:

Java 类型类型描述符
charC
byteB
shortS
intI
longJ
floatF
doubleD
booleanZ
voidV
对象L
数组[

基本类型的表示很简单,int 用 I 表示即可。对象的表示,如上图中父类 Object 的表示方法 Ljava/lang/Object;,再比如 String 类型,就用 Ljava/lang/String 表示。

对于数组,DalviK 有特殊的表示方法 [ 后面跟上数组元素的类型。int[] 的表示方式就是 [I, String[] 的表示方法是 [Ljava/lang/String;。二维数组用 [[ 表示,[[Ljava/lang/String 就是指 String[][],以此类推。

字段表示

# static fields
.field private static HELLO_WORLD:Ljava/lang/String; 

smali 中的字段以 .field 开头,并有 # static field(静态字段) 或者 # instance field(实例字段) 的注释。.field 之后分别是 访问修饰符,字段名称,冒号以及字段类型描述符。这句 smali 就声明了一个 String 类型名称为 HELLO_WORLD 的私有静态字段。

方法表示

smali 中的方法以 .method 开头。Hello.smali 中包含了三个方法,clinit , initmain 方法。main 方法是我们自己编写的,而 clinitinit 方法则是 javac 编译时生成的。下面进行逐一分析:

clinit

.method static constructor <clinit>()V
    .registers 1

    .prologue
    .line 3
    const-string v0, "Hello World!"

    sput-object v0, LHello;->HELLO_WORLD:Ljava/lang/String;

    return-void
.end method 

clinit 方法会进行静态变量的初始化,静态代码块的执行等操作,该方法在类被加载的时候调用。逐行分析该方法的执行逻辑:

到这里,clinit 方法就执行结束了。下面分析 init 方法。

init

.method public constructor <init>()V
    .registers 1

    .prologue
    .line 1
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    return-void
.end method 

其余各项与 clinit 方法相同,我们直接看执行的代码逻辑:

invoke-direct {p0}, Ljava/lang/Object;-><init>()V 

invoke-direct 用于调用非 static 直接方法(也就是说,本质上不可覆盖的实例方法,即 private 实例方法或构造函数)。显然,这里调用的是默认构造函数。

main

.method public static main([Ljava/lang/String;)V
    .registers 3

    .prologue
    .line 6
    sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;

    sget-object v1, LHello;->HELLO_WORLD:Ljava/lang/String;

    invoke-virtual {v0, v1}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

    .line 7
    return-void
.end method 

最后是 main 方法,从上述 smali 代码我们可以看到 main 方法使用了 3 个寄存器,无返回值(那是肯定的),执行的具体代码是下面三行:

sget-object v0, Ljava/lang/System;->out:Ljava/io/PrintStream;

sget-object v1, LHello;->HELLO_WORLD:Ljava/lang/String;

# 总结

Android架构学习进阶是一条漫长而艰苦的道路,不能靠一时激情,更不是熬几天几夜就能学好的,必须养成平时努力学习的习惯。**所以:贵在坚持!**

上面分享的字节跳动公司2021年的面试真题解析大全,笔者还把一线互联网企业主流面试技术要点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。
![](https://www.icode9.com/i/ll/?i=img_convert/00d748fb27f23d73a0a9395a913556d2.png)

**[CodeChina开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》](https://codechina.csdn.net/m0_60958482/android_p7)**

**【Android高级架构视频学习资源】**

 诸多细节。
[外链图片转存中...(img-MYLs318M-1630940389273)]

**[CodeChina开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》](https://codechina.csdn.net/m0_60958482/android_p7)**

**【Android高级架构视频学习资源】**

Android部分精讲视频领取学习后更加是如虎添翼!进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!

标签:lang,Ljava,String,必备,method,v0,面试,寄存器,Smali
来源: https://blog.csdn.net/m0_61418142/article/details/120147089