Java文件转换dex字节码指令集和查看汇编代码

不管是koltin 还是java文件,都会被jdk编译成中间代码:字节码文件。字节码文件在java执行引擎加载执行的时候,给到cpu的是汇编代码。

一个Java文件,想要查看他的Java代码的字节码。使用javap命令即可,如下代码,文件名MyDemo.java:

java 复制代码
public class MyDemo {
    public volatile static int a1;

    public static int fun1(){
        a1++;
        return a1;
    }
    public static void main(String[] args) {
        System.out.println("Hello world!");
        MyDemo.fun1();
    }
}
bash 复制代码
javap -c -s -v MyDemo >MyDemo.txt

-c 表示将代码进行反汇编

-s 表示输出内部类型签名

-v 表示输出附加信息

-l 输出行号和本地变量表

如图:

如果想要查看dex的字节码指令集,则先编译为.class, 在使用dx工具输出,操作步骤如下:

首先配置如下路径为环境变量

{Android-sdk}/build-tools/{版本}

如我的环境变量路径:

bash 复制代码
export ANDROID_HOME=/Users/xxx/Library/Android/sdk 
export PATH=`$PATH:$`ANDROID_HOME/build-tools/30.0.3

注意如要查看/build-tools/{版本}下是否有dx工具,如图所示:

如图:

在高版本如33以上的已经将dx工具和d8合并。暂时还不知道怎么在高版本使用,如有知道的小伙伴评论区告诉我吧。

bash 复制代码
javac MyDemo.java 
dx --dex --verbose --dump-to=MyDemo.dex.txt --dump-method=MyDemo.fun1  --verbose-dump MyDemo.class

如果你出现如下错误:

PARSE ERROR: unsupported class file version 55.0

报错的55.0是java 11的类文件格式版本号,说明dx工具版本比当前你的java版本低。那就将java的环境变量配置成低版本的。我的环境是java 8 执行这个命令成功。如图所示:

如图:

去除多余信息:

arduino 复制代码
  0000: sget v0, MyDemo.a1:I // field@0000
  0002: add-int/lit8 v0, v0, #int 1 // #01
  0004: sput v0, MyDemo.a1:I // field@0000
  0006: sget v0, MyDemo.a1:I // field@0000
  0008: return v0
  0009: code-address

对比java字节码指令和dex指令。dex指令少了。代码比较简单,小伙伴本可以试试复杂一点,指令可能会少更多,至于原因可以看java虚拟机和Android虚拟机的不同。

而有时候想看某些JDK底层实现,想要查看Java代码最真实的运行细节,即查看字节码对应的机器码,即汇编代码。需要一个工具:

hsdis-amd64.dylib

Mac下:github.com/evolvedmicr...

下载下来后,将其放置到jre/lib目录下即可。

其他平台,可去(hllvm.group.iteye.com/)中下载。

可以使用命令

java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly MyDemo (MyDemo是class文件) > MyDemo.asm

文件可能很大.如果只想看某个方法的汇编代码,使用如下命令;

java -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:CompileCommand=compileonly,MyDemo.fun1 MyDemo > MyDemofun1.asm

如图所示:

如图:

其中有一个lock指令,是java代码通过硬件层面的指令实现volatile关键字的能力。关于volatile关键字的实现原理和作用可以查看《从汇编指令搞懂volatile关键字》

相关推荐
xlxxy_5 分钟前
sap获取批次特性报表
java·linux·开发语言·前端·数据库·abap·mm
栋***t16 分钟前
从“工具”到“基建”,麦塔在线考试系统经历的时代变局与定位逻辑
java·大数据·数据库·开源软件·无纸化
欢喜躲在眉梢里24 分钟前
用飞算Java做了一套新能源充电运营管理系统:把站点、设备、订单拆成可运营的微服务
java·开发语言·微服务·ai编程·技术分享·java开发·飞算javaai炫技赛
薛定猫AI28 分钟前
【技术干货】大模型文档结构化提取实战:Python解析PDF发票并批量生成CSV
java·python·pdf
咖啡八杯41 分钟前
GoF设计模式——状态模式
java·面试·架构
荣码43 分钟前
Prompt工程实战:同一个需求换3种写法,效果差10倍
java·python
weixin_422329311 小时前
AgentScope Java ReActAgent 核心循环深度解析
java·开发语言·人工智能
952361 小时前
RabbitMQ - 高级特性
java·spring boot·分布式·后端·rabbitmq
尽兴-1 小时前
传统 Java/Vue 系统如何一步步接入 AI 维护
java·vue.js·人工智能·ai·大模型
shuoshuohaohao1 小时前
《HTTP协议》
java·web