字节码编程ASM之两数之和

写在前面

源码 。
看下如何使用ASM来写如下的类:

package com.dahuyou.demo.asm;public class AsmSumOfTwo {public AsmSumOfTwo() {}public static void main(String[] var0) {int var1 = (new AsmSumOfTwo()).sum(1, 2);System.out.println(var1);}public int sum(int var1, int var2) {return var1 + var2;}
}

1:编码

源码:

package com.dahuyou.asm.helloworld;import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;public class SumOfTwo extends ClassLoader {public static void main(String[] args) throws Exception {// 生成二进制字节码byte[] bytes = generate();// 输出字节码outputClazz(bytes);// 加载AsmHelloWorldClass<?> clazz = new SumOfTwo().defineClass("com.dahuyou.demo.asm.AsmSumOfTwo", bytes, 0, bytes.length);// 反射获取 main 方法Method main = clazz.getMethod("main", String[].class);// 调用 main 方法main.invoke(null, new Object[]{new String[]{}});}private static byte[] generate() {ClassWriter classWriter = new ClassWriter(0);{MethodVisitor mv = classWriter.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);mv.visitCode();// aload指令,加载本地变量表0位置对象(a)mv.visitVarInsn(Opcodes.ALOAD, 0);// invokespecial指令,调用方法<init>mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V");// return指令,返回voidmv.visitInsn(Opcodes.RETURN);// 操作数栈,局部变量表大小mv.visitMaxs(1, 1);mv.visitEnd();}// 定义对象头;版本号、修饰符、全类名、签名、父类、实现的接口classWriter.visit(Opcodes.V1_7, Opcodes.ACC_PUBLIC, "com/dahuyou/demo/asm/AsmSumOfTwo", null, "java/lang/Object", null);// 添加方法;修饰符、方法名、描述符、签名、异常MethodVisitor methodVisitor = classWriter.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);// int var1 = (new AsmSumOfTwo()).sum(1, 2);中的 new AsmSumOfTwo(),即创建实例对象,并压入操作数栈栈顶methodVisitor.visitTypeInsn(Opcodes.NEW, "com/dahuyou/demo/asm/AsmSumOfTwo");// 获取操作数栈栈顶元素,并复制,重新压回,此时操作数栈栈顶有连续的两个new AsmSumOfTwo()引用methodVisitor.visitInsn(Opcodes.DUP);// 栈顶元素出栈,并调用初始化方法<init>,即默认的空构造函数methodVisitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "com/dahuyou/demo/asm/AsmSumOfTwo", "<init>", "()V");// iconst 加载整数常量 1,2,并压到栈顶,此时,操作数栈元素为2,1,AsmSumOfTwo实例引用methodVisitor.visitInsn(Opcodes.ICONST_1);methodVisitor.visitInsn(Opcodes.ICONST_2);// int var1 = (new AsmSumOfTwo()).sum(1, 2);中的.sum(1, 2) (II)I入参两个int,返回int,函数的结果存储栈顶methodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "com/dahuyou/demo/asm/AsmSumOfTwo", "sum", "(II)I");// 将栈顶元素存储到本地变量表 slot 1位置,即赋值给var1(实际程序运行过程中jvm是不关心变量名称的,因为完全不影响运行结果)methodVisitor.visitVarInsn(Opcodes.ISTORE, 1);// 获取静态属性System.outmethodVisitor.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");// 将本地变量表中slot 1位置的int变量推动到操作数栈栈顶(因为要做sout)methodVisitor.visitVarInsn(Opcodes.ILOAD, 1);// 获取栈顶元素,并作sout,这样int var1 = (new AsmSumOfTwo()).sum(1, 2);的var1就完成打印了// (I)V参数int,返回voidmethodVisitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(I)V");// 返回methodVisitor.visitInsn(Opcodes.RETURN);// 设置操作数栈的深度和局部变量的大小methodVisitor.visitMaxs(3, 2);// 方法结束methodVisitor.visitEnd();/*** 以下代码定义如下的函数:* public int sum(int i, int m) {*     return i + m;* }*/MethodVisitor methodVisitor_sum = classWriter.visitMethod(Opcodes.ACC_PUBLIC, "sum", "(II)I", null, null);// 加载本地变量表slot 1,2位置int变量到操作数栈,并调用add指令执行加法methodVisitor_sum.visitVarInsn(Opcodes.ILOAD, 1);methodVisitor_sum.visitVarInsn(Opcodes.ILOAD, 2);methodVisitor_sum.visitInsn(Opcodes.IADD);// 返回methodVisitor_sum.visitInsn(Opcodes.IRETURN);// 设置操作数栈的深度和局部变量的大小methodVisitor_sum.visitMaxs(2, 3);methodVisitor_sum.visitEnd();// 类完成classWriter.visitEnd();// 生成字节数组return classWriter.toByteArray();}private static void outputClazz(byte[] bytes) {// 输出类字节码FileOutputStream out = null;try {out = new FileOutputStream("AsmSumOfTwo.class");System.out.println("ASM类输出路径:" + (new File("")).getAbsolutePath());out.write(bytes);} catch (Exception e) {e.printStackTrace();} finally {if (null != out) try {out.close();} catch (IOException e) {e.printStackTrace();}}}}

写了非常详细的注释,看下吧,还有哪里不懂的可以留言告知。然后运行下:
在这里插入图片描述
反编译看对应的Java代码:
在这里插入图片描述

写在后面

一个多么简单的加法函数,通过底层字节码方式来编写还是挺麻烦的,只能说底层还是很复杂的,但是想要进阶,不了解底层又是不行的。所以,在这winter already coming的行业环境下,加油吧!!!

参考文章列表

JVM 虚拟机字节码指令表 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/36244.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NEFU算法设计与分析课程设计

&#xff08;一&#xff09;动态规划问题 最大子矩阵问题 【题目描述】 有一个包含正数和负数的二维数组。一个子矩阵是指在该二维数据里&#xff0c;任意相邻的下标是1 * 1或更大的子数组。一个子矩阵的和是指该子矩阵中所有元素的和。本题中&#xff0c;把具有最大和的子矩…

Batch学习及应用案例

一、介绍 Batch是一种Windows操作系统中使用的批处理脚本语言&#xff0c;用于自动化执行一系列命令和操作。通过编写批处理脚本&#xff0c;可以实现自动化完成重复性或繁琐的任务&#xff0c;提高工作效率。 Batch脚本可以使用内置的命令和命令行工具&#xff0c;以及调用其…

2024.06.27【读书笔记】|医疗科技创新流程(第1章:需求发现 第一部分)【AI增强版】

第1章&#xff1a;需求发现 (Needs Finding) 1.1 战略聚焦 (Strategic Focus) 战略聚焦是医疗技术创新过程的起点。它要求创新者明确自己的使命、评估自身的强项与弱点&#xff0c;并据此确定项目接受标准。以下是对1.1小节的详细介绍&#xff1a; 定义使命&#xff1a;创新者…

使用飞书多维表格实现推送邮件

一、为什么用飞书&#xff1f; 在当今竞争激烈的商业环境中&#xff0c;选择一款高效、智能的办公工具至关重要。了解飞书的朋友应该都知道&#xff0c;飞书的集成能力是很强大的&#xff0c;能够与各种主流的办公软件无缝衔接&#xff0c;实现数据交互&#xff0c;提升工作效…

【Linux】防火墙命令

文章目录 1. 启动、停止和重启防火墙2. 防火墙状态查询3. 防火墙规则配置4. 防火墙规则查询5. 防火墙其他常用命令 1. 启动、停止和重启防火墙 启动防火墙&#xff1a;systemctl start firewalld停止防火墙&#xff1a;systemctl stop firewalld重启防火墙&#xff1a;systemc…

Gemalto SafeNet Luna HSM服务器硬件监控指标解读

在现代化的信息安全体系中&#xff0c;硬件安全模块&#xff08;HSM&#xff09;扮演着至关重要的角色&#xff0c;它负责保护和管理敏感的数据和密钥。Gemalto SafeNet Luna HSM作为一款高性能的硬件安全模块&#xff0c;广泛应用于金融、政府和企业等领域。为了确保Luna HSM的…

竞赛选题 python区块链实现 - proof of work工作量证明共识算法

文章目录 0 前言1 区块链基础1.1 比特币内部结构1.2 实现的区块链数据结构1.3 注意点1.4 区块链的核心-工作量证明算法1.4.1 拜占庭将军问题1.4.2 解决办法1.4.3 代码实现 2 快速实现一个区块链2.1 什么是区块链2.2 一个完整的快包含什么2.3 什么是挖矿2.4 工作量证明算法&…

vue3中通过vditor插件实现自定义上传图片、录入echarts、脑图、markdown语法的编辑器

1、下载Vditor插件 npm i vditor 我的vditor版本是3.10.2&#xff0c;大家可以自行选择下载最新版本 官网&#xff1a;Vditor 一款浏览器端的 Markdown 编辑器&#xff0c;支持所见即所得&#xff08;富文本&#xff09;、即时渲染&#xff08;类似 Typora&#xff09;和分屏 …

消息队列选型之 Kafka vs RabbitMQ

在面对众多的消息队列时&#xff0c;我们往往会陷入选择的困境&#xff1a;“消息队列那么多&#xff0c;该怎么选啊&#xff1f;Kafka 和 RabbitMQ 比较好用&#xff0c;用哪个更好呢&#xff1f;”想必大家也曾有过类似的疑问。对此本文将在接下来的内容中以 Kafka 和 Rabbit…

阿里AI-Spring Cloud Alibaba AI:快速搭建自己的通义千问

本文基于官方文档。 Spring AI 官方文档&#xff1a;Spring AI :: Spring AI Reference 中文文档&#xff1a;Spring AI 简介 - spring 中文网 (springdoc.cn) Spring AI 是 Spring 官方社区项目&#xff0c;旨在简化 Java AI 应用程序开发&#xff0c;让 Java 开发者像使用…

流光卡片,生成炫酷文字,开源API

https://fireflycard.shushiai.com/ 这是我的一个网站&#xff0c;流光卡片&#xff0c;主要功能是帮你制作酷炫的文字卡片&#xff0c;用精美的卡片让你的文字生动起来。 展示效果如下&#xff1a; 你可以用它制作卡片&#xff0c;来记录自己的表达。支持设定卡片背景、LOGO…

梗图生成器突然爆红;ElevenLabs发布IOS APP 高质量语音朗读手机各种文本内容;开源工作流架构ControlFlow

✨ 1: 梗图生成器 fabianstelzer 在Glif做的一个超强meme生成器 Glif 是一个工作流&#xff0c;能生成文字图片和视频&#xff0c;用工作流的形式可以完成很多的花样来。 最近爆红的梗图生成器&#xff0c;WOJAK MEME GENERATOR &#xff0c;也是用工作流的形式来生成这些有…

MetaGPT全面安装与配置指南

文章目录 MetaGPT环境配置1.1 检查Python版本1.2 拉取MetaGPT仓库1.3 拉取源码本地安装1.4 MetaGPT安装成果全流程展示1.5 尝试简单使用 MetaGPT的API调用2.1 本地部署大模型尝试安装必要的依赖下载并配置大模型配置API服务 2.2 讯飞星火API调用获取API密钥安装讯飞星火SDK调用…

宝塔面板之 wwwroot修改不了权限

宝塔使用Apache环境&#xff0c;搭建网站出现 You don’t have permission to access this resource.Server unable to read h出错时的解决办法 今天由于某些原因导致我宝塔 在Apache和Nginx运行环境下不断切换&#xff0c;结果我网站全部不能正常打不开了 结果我发现原本宝塔…

boss直聘招聘数据可视化分析

boss直聘招聘数据可视化分析 一、数据预处理二、数据可视化三、完整代码一、数据预处理 在 上一篇博客中,笔者已经详细介绍了使用selenium爬取南昌市web前端工程师的招聘岗位数据,数据格式如下: 这里主要对薪水列进行处理,为方便处理,将日薪和周薪的数据删除,将带有13薪…

1027. 最长等差数列(leetcode)

1027. 最长等差数列&#xff08;leetcode&#xff09; 题目描述 给你一个整数数组 nums&#xff0c;返回 nums 中最长等差子序列的长度。 回想一下&#xff0c;nums 的子序列是一个列表 nums[i1], nums[i2], …, nums[ik] &#xff0c;且 0 < i1 < i2 < … < ik &…

自媒体内容创作者必备:ChatGPT助你提升文章质量

随着自媒体的迅猛发展&#xff0c;越来越多的人加入到内容创作的行列。然而&#xff0c;要在这个竞争激烈的领域脱颖而出&#xff0c;不仅需要创意和独特的观点&#xff0c;更需要高质量的文章内容。在这方面&#xff0c;ChatGPT作为一个智能写作助手&#xff0c;能够帮助自媒体…

Dilworth定理学习笔记

最近做了两道题&#xff0c;都涉及到了这个定理&#xff0c;虽然我都没有用&#xff0c;不过学会这个定理确实有很多好处。 第一道是[TJOI2015] 组合数学&#xff0c;让你在一个矩阵中用最少的只能往右和往下的路径覆盖掉全部的点&#xff08;点有权值&#xff09;。这道题我一…

【区分vue2和vue3下的element UI Message 消息提示组件,分别详细介绍属性,事件,方法如何使用,并举例】

在 Vue 2 中&#xff0c;我们通常使用 Element UI 的 this.$message 方法来显示消息提示&#xff0c;而不是作为一个组件直接在模板中使用。然而&#xff0c;在 Vue 3 的 Element Plus 中&#xff0c;虽然 this.$message 的使用方式仍然保留&#xff0c;但官方文档可能更倾向于…

靠!AI绘画月入过万!是否现实?

前言 AI人工智能已经出现在了越来越多领域中&#xff0c;比如最近一段时间&#xff0c;AI绘画就受到了许多人的关注&#xff0c;一来&#xff0c;其背后隐藏的版权问题、替代性问题引发了人们的广泛讨论&#xff0c;再者&#xff0c;AI绘画在短期时间内成为了流量密码&#xf…