天天看点

smali语言入门 内部类

有了前面的smali操作流学习 

https://blog.csdn.net/qq_20330595/article/details/80995424

我们在他的基础上再加点内部类玩下

对你之前的代码 确实看了心 凉了半截 

参考 https://blog.csdn.net/lostinai/article/details/48975661

按照他的意思 应该有两个文件 这里起声明作用。

# annotations
.annotation system Ldalvik/annotation/MemberClasses;
    value = {
        Lcom/example/hellojni/Jieyou$Show;
    }
.end annotation
.field private show:Lcom/example/hellojni/Jieyou$Show;
申明成员变量 show
           
# direct methods
.method public constructor <init>(Ljava/lang/String;IDLcom/example/hellojni/Jieyou$Show;)V
    .registers 7
     一共p1-p7七个寄存器
    .param p1, "name"    # Ljava/lang/String;
    .param p2, "age"    # I
    .param p3, "height"    # D
    .param p5, "show"    # Lcom/example/hellojni/Jieyou$Show;
     声明参数 寄存器托管
    .prologue
    .line 24
    invoke-direct {p0}, Ljava/lang/Object;-><init>()V
     在java源码第24行开始运行代 new 一个 Test实例
    .line 25
    iput-object p1, p0, Lcom/example/hellojni/Jieyou;->name:Ljava/lang/String;
    对象赋值  参考  https://www.cnblogs.com/lee0oo0/p/3728271.html
    给p0(test)的name赋值 p1("name")
    .line 26
    iput p2, p0, Lcom/example/hellojni/Jieyou;->age:I
    给p0(test)的name赋值 p1("age")
    .line 27
    iput-wide p3, p0, Lcom/example/hellojni/Jieyou;->height:D
    给p0(test)的name赋值 p1("height")
    .line 28
    iput-object p5, p0, Lcom/example/hellojni/Jieyou;->show:Lcom/example/hellojni/Jieyou$Show;
    给p0(test)的name赋值 p1("show")
    .line 29
    return-void
.end method                https://www.cnblogs.com/lee0oo0/p/3728271.html
    给p0(test)的name赋值 p1("name")
    .line 26
    iput p2, p0, Lcom/example/hellojni/Jieyou;->age:I
    给p0(test)的name赋值 p1("age")
    .line 27
    iput-wide p3, p0, Lcom/example/hellojni/Jieyou;->height:D
    给p0(test)的name赋值 p1("height")
    .line 28
    iput-object p5, p0, Lcom/example/hellojni/Jieyou;->show:Lcom/example/hellojni/Jieyou$Show;
    给p0(test)的name赋值 p1("show")
    .line 29
    return-void
.end method      

在方法 main 中 

  对应java中的19行 也就是 
  Jieyou jieyou = new Jieyou("马齐", 12, 178, new Show());

 .line 19
    :cond_30
    new-instance v1, Lcom/example/hellojni/Jieyou;
    创建实例 给 v1
    const-string v2, "\u9a6c\u9f50"
    创建字符串 "马齐"给v2
    const/16 v3, 0xc
    给v3一个长度为16的整数 12
    const-wide v4, 0x4066400000000000L    # 178.0
    参考 https://blog.csdn.net/dd864140130/article/details/52076515
    数据定义指令 :将数值符号扩展为64位后赋值个寄存器对v4
    new-instance v6, Lcom/example/hellojni/Jieyou$Show;
    创建show实例给v6
    invoke-direct {v6}, Lcom/example/hellojni/Jieyou$Show;-><init>()V
    调用v6的构造函数 
    invoke-direct/range {v1 .. v6}, Lcom/example/hellojni/Jieyou;-><init>(Ljava/lang/String;IDLcom/example/hellojni/Jieyou$Show;)V
    调用v1(Jieyou)的有参构造函数 参数为v2-v6;
    PS:再此强调一遍对于非静态方法而言{}的结构是{当前实例对象,参数1,参数2,…参数n},而对于静态方法而言则是{参数1,参数2,…参数n}
    这里的参数排列貌似并非绝对的使用;隔开因此我们做个试验如下                https://blog.csdn.net/dd864140130/article/details/52076515
    数据定义指令 :将数值符号扩展为64位后赋值个寄存器对v4
    new-instance v6, Lcom/example/hellojni/Jieyou$Show;
    创建show实例给v6
    invoke-direct {v6}, Lcom/example/hellojni/Jieyou$Show;-><init>()V
    调用v6的构造函数 
    invoke-direct/range {v1 .. v6}, Lcom/example/hellojni/Jieyou;-><init>(Ljava/lang/String;IDLcom/example/hellojni/Jieyou$Show;)V
    调用v1(Jieyou)的有参构造函数 参数为v2-v6;
    PS:再此强调一遍对于非静态方法而言{}的结构是{当前实例对象,参数1,参数2,…参数n},而对于静态方法而言则是{参数1,参数2,…参数n}
    这里的参数排列貌似并非绝对的使用;隔开因此我们做个试验如下      
    新增一个参数“”,编译后结果为
    Jieyou jieyou = new Jieyou("马齐", 12,"", 178, new Show());
    invoke-direct/range {v0 .. v6}, Lcom/example/hellojni/Jieyou;-><init>(Ljava/lang/String;ILjava/lang/String;DLcom/example/hellojni/Jieyou$Show;)V
    由此我们可以得出结论 基本数据类型  和 非基本数据类型 共同为参数时候 可以省略;
                由此我们可以得出结论 基本数据类型  和 非基本数据类型 共同为参数时候 可以省略;
      

接下来

.line 20
    .local v0, "jieyou":Lcom/example/hellojni/Jieyou;
    iget-object v1, v0, Lcom/example/hellojni/Jieyou;->show:Lcom/example/hellojni/Jieyou$Show;
    可以看到iget-object指令比sget-object多了一个参数,就是该变量所在类的实例,在这里就是v0即“this”。
    也就是v0就是jieyou 为什么用这个指令呢?因为Show为static类型
    这边 参考 https://blog.csdn.net/lpohvbe/article/details/7981386
    invoke-virtual {v1}, Lcom/example/hellojni/Jieyou$Show;->getShowtime()J
    调用 v1(show)函数getShowtime
    move-result-wide v10
    将上一个invoke指令操作的双字(64位)非对象结果赋值给v10寄存器
    .line 21
    .local v10, "showtime":J
    J表示Long类型 
    sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
    获取非静态成员实例 out 
    invoke-virtual {v1, v10, v11}, Ljava/io/PrintStream;->println(J)V
    调用out的println方法  v1 为out  v10 v11 为参数 showtime 和 v11可能是"\n"吧?(一脸蒙蔽中)                可以看到iget-object指令比sget-object多了一个参数,就是该变量所在类的实例,在这里就是v0即“this”。
    也就是v0就是jieyou 为什么用这个指令呢?因为Show为static类型
    这边 参考 https://blog.csdn.net/lpohvbe/article/details/7981386
    invoke-virtual {v1}, Lcom/example/hellojni/Jieyou$Show;->getShowtime()J
    调用 v1(show)函数getShowtime
    move-result-wide v10
    将上一个invoke指令操作的双字(64位)非对象结果赋值给v10寄存器
    .line 21
    .local v10, "showtime":J
    J表示Long类型 
    sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
    获取非静态成员实例 out 
    invoke-virtual {v1, v10, v11}, Ljava/io/PrintStream;->println(J)V
    调用out的println方法  v1 为out  v10 v11 为参数 showtime 和 v11可能是"\n"吧?(一脸蒙蔽中)      
    .line 22
    方法结束
    return-void
    .line 13
    nop
    站位对齐代码 https://blog.csdn.net/wizardforcel/article/details/54730253                https://blog.csdn.net/wizardforcel/article/details/54730253      

我们再来看看Jieyou$Smali

.class public Lcom/example/hellojni/Jieyou$Show;
.super Ljava/lang/Object;
.source "Jieyou.java"
不解释

# annotations
.annotation system Ldalvik/annotation/EnclosingClass;
    value = Lcom/example/hellojni/Jieyou;
.end annotation
貌似每个内部类都会有这个EnclosingClass申明

.annotation system Ldalvik/annotation/InnerClass;
    accessFlags = 0x9
    name = "Show"
.end annotation
起名Show  
关于accessFlages 访问标记  https://blog.csdn.net/a18922723593/article/details/49516145

# virtual methods
.method public getShowtime()J
    .registers 3

    .prologue
    .line 33
    new-instance v0, Ljava/util/Date;

    invoke-direct {v0}, Ljava/util/Date;-><init>()V

    invoke-virtual {v0}, Ljava/util/Date;->getTime()J

    move-result-wide v0
    整个过程就是实例化Date对象 调用 getTime函数并返回。 
    return-wide v0
    扩展成64位返回
.end method

                访问标记  https://blog.csdn.net/a18922723593/article/details/49516145

# virtual methods
.method public getShowtime()J
    .registers 3

    .prologue
    .line 33
    new-instance v0, Ljava/util/Date;

    invoke-direct {v0}, Ljava/util/Date;-><init>()V

    invoke-virtual {v0}, Ljava/util/Date;->getTime()J

    move-result-wide v0
    整个过程就是实例化Date对象 调用 getTime函数并返回。 
    return-wide v0
    扩展成64位返回
.end method

      

=============================================源码部分============================================

package com.example.hellojni;

import java.util.Date;

public class Jieyou {
    public String name;
    private int age;
    protected double height;
    private Show show;


    public static void main(String[] args) {
        int[] posAry = new int[]{5, 4, 6, 11, 11, 12, 14, 5, 7, 5, 15, 4, 6, 10, 3, 7, 1, 13, 10, 0, 8};
        char[] websiteAry = new char[]{'3', 'o', '1', 'w', 'h', 't', 'w', 'm', '6', 'c', ':', 'n', 'p', '/', '.', 'w'};
        System.out.print("jieyouwang");
        for (int i = 0; i < posAry.length; i++) {
            System.out.print(websiteAry[i % 2 == 0 ? posAry[i] - 1 : posAry[i] + 1]);
        }
        Jieyou jieyou = new Jieyou("马齐", 12, 178, new Show());
        long showtime = jieyou.show.getShowtime();
        System.out.println(showtime);
    }

    public Jieyou(String name, int age, double height, Show show) {
        this.name = name;
        this.age = age;
        this.height = height;
        this.show = show;
    }

    public static class Show {
        public long getShowtime() {
            return new Date().getTime();
        }
    }
}
           

Jieyou.smali

.class public Lcom/example/hellojni/Jieyou;
.super Ljava/lang/Object;
.source "Jieyou.java"


# annotations
.annotation system Ldalvik/annotation/MemberClasses;
    value = {
        Lcom/example/hellojni/Jieyou$Show;
    }
.end annotation


# instance fields
.field private age:I

.field protected height:D

.field public name:Ljava/lang/String;

.field private show:Lcom/example/hellojni/Jieyou$Show;


# direct methods
.method public constructor <init>(Ljava/lang/String;IDLcom/example/hellojni/Jieyou$Show;)V
    .registers 7
    .param p1, "name"    # Ljava/lang/String;
    .param p2, "age"    # I
    .param p3, "height"    # D
    .param p5, "show"    # Lcom/example/hellojni/Jieyou$Show;

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

    .line 25
    iput-object p1, p0, Lcom/example/hellojni/Jieyou;->name:Ljava/lang/String;

    .line 26
    iput p2, p0, Lcom/example/hellojni/Jieyou;->age:I

    .line 27
    iput-wide p3, p0, Lcom/example/hellojni/Jieyou;->height:D

    .line 28
    iput-object p5, p0, Lcom/example/hellojni/Jieyou;->show:Lcom/example/hellojni/Jieyou$Show;

    .line 29
    return-void
.end method

.method public static main([Ljava/lang/String;)V
    .registers 12
    .param p0, "args"    # [Ljava/lang/String;

    .prologue
    .line 13
    const/16 v2, 0x15

    new-array v7, v2, [I

    fill-array-data v7, :array_50

    .line 14
    .local v7, "posAry":[I
    const/16 v2, 0x10

    new-array v10, v2, [C

    fill-array-data v10, :array_7e

    .line 15
    .local v10, "websiteAry":[C
    sget-object v2, Ljava/lang/System;->out:Ljava/io/PrintStream;

    const-string v3, "jieyouwang"

    invoke-virtual {v2, v3}, Ljava/io/PrintStream;->print(Ljava/lang/String;)V

    .line 16
    const/4 v0, 0x0

    .local v0, "i":I
    :goto_16
    array-length v2, v7

    if-ge v0, v2, :cond_30

    .line 17
    sget-object v3, Ljava/lang/System;->out:Ljava/io/PrintStream;

    rem-int/lit8 v2, v0, 0x2

    if-nez v2, :cond_2b

    aget v2, v7, v0

    add-int/lit8 v2, v2, -0x1

    :goto_23
    aget-char v2, v10, v2

    invoke-virtual {v3, v2}, Ljava/io/PrintStream;->print(C)V

    .line 16
    add-int/lit8 v0, v0, 0x1

    goto :goto_16

    .line 17
    :cond_2b
    aget v2, v7, v0

    add-int/lit8 v2, v2, 0x1

    goto :goto_23

    .line 19
    :cond_30
    new-instance v1, Lcom/example/hellojni/Jieyou;

    const-string v2, "\u9a6c\u9f50"

    const/16 v3, 0xc

    const-wide v4, 0x4066400000000000L    # 178.0

    new-instance v6, Lcom/example/hellojni/Jieyou$Show;

    invoke-direct {v6}, Lcom/example/hellojni/Jieyou$Show;-><init>()V

    invoke-direct/range {v1 .. v6}, Lcom/example/hellojni/Jieyou;-><init>(Ljava/lang/String;IDLcom/example/hellojni/Jieyou$Show;)V

    .line 20
    .local v1, "jieyou":Lcom/example/hellojni/Jieyou;
    iget-object v2, v1, Lcom/example/hellojni/Jieyou;->show:Lcom/example/hellojni/Jieyou$Show;

    invoke-virtual {v2}, Lcom/example/hellojni/Jieyou$Show;->getShowtime()J

    move-result-wide v8

    .line 21
    .local v8, "showtime":J
    sget-object v2, Ljava/lang/System;->out:Ljava/io/PrintStream;

    invoke-virtual {v2, v8, v9}, Ljava/io/PrintStream;->println(J)V

    .line 22
    return-void

    .line 13
    nop

    :array_50
    .array-data 4
        0x5
        0x4
        0x6
        0xb
        0xb
        0xc
        0xe
        0x5
        0x7
        0x5
        0xf
        0x4
        0x6
        0xa
        0x3
        0x7
        0x1
        0xd
        0xa
        0x0
        0x8
    .end array-data

    .line 14
    :array_7e
    .array-data 2
        0x33s
        0x6fs
        0x31s
        0x77s
        0x68s
        0x74s
        0x77s
        0x6ds
        0x36s
        0x63s
        0x3as
        0x6es
        0x70s
        0x2fs
        0x2es
        0x77s
    .end array-data
.end method
           

Jieyou$Show.smali

.class public Lcom/example/hellojni/Jieyou$Show;
.super Ljava/lang/Object;
.source "Jieyou.java"


# annotations
.annotation system Ldalvik/annotation/EnclosingClass;
    value = Lcom/example/hellojni/Jieyou;
.end annotation

.annotation system Ldalvik/annotation/InnerClass;
    accessFlags = 0x9
    name = "Show"
.end annotation


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

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

    return-void
.end method


# virtual methods
.method public getShowtime()J
    .registers 3

    .prologue
    .line 33
    new-instance v0, Ljava/util/Date;

    invoke-direct {v0}, Ljava/util/Date;-><init>()V

    invoke-virtual {v0}, Ljava/util/Date;->getTime()J

    move-result-wide v0

    return-wide v0
.end method
           

继续阅读