asm生成for循环语句方法

硅谷探秘者 1744 0 0


asm生成for循环语句方法

1.jar包


2.原java文件

package club.jiajia.test3;
public class Examp4 {
	public int method(int a){
		int r=0;
		for(int i=0;i<a;i++){
			r++;
		}
		return r;
	}
}

3.javap -c命令反编译此java的字节码文件

Compiled from "Examp4.java"
public class club.jiajia.test3.Examp4 {
  public club.jiajia.test3.Examp4();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public int method(int);
    Code:
       0: iconst_0	//-将int类型的0推送到栈顶
       1: istore_2	//-将栈顶int型数值存入第三个本地变量  r 
       2: iconst_0	//-将int型0推送至栈顶
       3: istore_3	//-将栈顶int型数值存入第四个本地变量 i
       4: iload_3	//-将第四个int型本地变量推送至栈顶
       5: iload_1	//-将第二个int型本地变量推送至栈顶
       6: if_icmpge     18	//-比较栈顶两int型数值大小,当结果大于等于0时跳转
       9: iinc          2, 1	//-将指定int型变量增加指定值
      12: iinc          3, 1	//-将指定int型变量增加指定值
      15: goto          4	//-无条件跳转
      18: iload_2	//-将第四个int型本地变量推送至栈顶
      19: ireturn	//-返回一个int值
}

“//-”是我自己写的注释


    在此只关注method方法

4.按照上面的字节码文件编写java代码如下:

package club.jiajia.test3;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
public class TestAsm4 implements Opcodes{
	public static void main(String[] args) throws InstantiationException, IllegalAccessException{
		ClassWriter cw=new ClassWriter(0);
		String className="Example4";
		cw.visit(0x31,ACC_PUBLIC,className,null,"java/lang/Object",new String[]{"java/lang/Cloneable",ITest.class.getName().replace('.','/')});
		String method="method";
		MethodVisitor mv;
		
		/***********************************************************/
		Label end = new Label();
		mv=cw.visitMethod(ACC_PUBLIC,method,"(I)I",null,null);
		mv.visitCode();
		mv.visitInsn(ICONST_0);
		mv.visitVarInsn(ISTORE,2);
		mv.visitInsn(ICONST_0);
		mv.visitVarInsn(ISTORE,3);
		
		Label f=new Label();
		mv.visitLabel(f);
		mv.visitFrame(F_SAME, 0, null, 0, null);
		mv.visitVarInsn(ILOAD,3);
		mv.visitVarInsn(ILOAD,1);
		mv.visitJumpInsn(IF_ICMPGE, end);
		mv.visitIincInsn(2,1);
		mv.visitIincInsn(3,1);
		mv.visitJumpInsn(GOTO, f);
		
		mv.visitLabel(end);
		mv.visitFrame(F_SAME, 0, null, 0, null);

		mv.visitVarInsn(ILOAD,2);
		mv.visitInsn(IRETURN);
		
		mv.visitMaxs(2, 4);
		mv.visitEnd();
		
		/***********************************************************/
		
		//下面产生构造方法
		mv=cw.visitMethod(ACC_PUBLIC,"<init>","()V",null,null);
		mv.visitCode();
		mv.visitVarInsn(ALOAD,0);
		mv.visitMethodInsn(INVOKESPECIAL,"java/lang/Object","<init>","()V");
		mv.visitInsn(RETURN);
		mv.visitMaxs(1,1);
		mv.visitEnd();
		
		cw.visitEnd();

		byte[] bs=cw.toByteArray();
		File file = new File("E://jiajiajia/Example4.class");
		try {
			FileOutputStream fout = new FileOutputStream(file);
			fout.write(bs);
			fout.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		MyCLassLoader loader=new MyCLassLoader();
		Class<?> c=loader.defineClass(bs);
		
		ITest ins=(ITest)c.newInstance();
		System.out.println(ins.method(123));
	}
	public interface ITest{
		public int method(int a);
	}
	public static class MyCLassLoader extends ClassLoader{
		public Class<?> defineClass(byte[] data){
			return super.defineClass(null,data,0,data.length,null);
		}
	}
}


5.反编译生成的class文件如下:

menu.saveimg.savepath20190322140923.jpg


猜你喜欢
java基础 1996 1.jar包:2.原java文件:packageclub.jiajia.test3;publicclassExamp3{ publicintmethod(inta){ switch(a){ case123: a=1230; break; case128: a=1280; break; case12: a=120; break; } returna
java基础 2571 asm动态类和getandset1.自定义类加载器packageclub.jiajia.test;publicclassMyClassLoaderextendsClassLoader
java基础 2352 asm实例对象的调用1.需要的jar包2.我们需要通过asm的目标类如下:packageclub.jiajia.test3;publicclassExamp5
数据库基础 1767 两种用:简单case函数casesexwhen'1'then'男'when'2'then'女’else'其他'endcase搜索函数casewhensex='1'then'男'whensex='2
java基础 813 ,跳出体等功能。而在结构化程序言中一般不主张使用goto,以免造程序流程的混乱,使理解和调试程序都产困难。但是在java言中,goto这个词只是作为了保留字,还没有使用。那是因为java
数据结构与算法 1056 约瑟夫问题描述有m个人,围一个,编号为1、2、3、、、m,从第一个人开始报数(从1开始数),假设数到n的那个人出局,然后从下一个人继续数数(从1开始数),数到n出列,以此,最后那个人为
数据库 1321 mysql批量更新不同的uuidsql:UPDATEusersetuuid=UUID();去掉中间的-UPDATEusersetuuid=REPLACE(uuid,"-","");注意这两个
weblog 1454 java使用原jdbc连接数据库获取数据或执行sql(mysql) publicvoidtest2(){ try{ //加载MySql的驱动类 Class.forName
归档
2018年11月  12 2018年12月  33 2019年01月  28 2019年02月  28 2019年03月  32 2019年04月  27 2019年05月  33 2019年06月  6 2019年07月  12 2019年08月  12 2019年09月  21 2019年10月  8 2019年11月  15 2019年12月  25 2020年01月  9 2020年02月  5 2020年03月  16 2020年04月  4 2020年06月  1 2020年07月  7 2020年08月  13 2020年09月  9 2020年10月  5 2020年12月  3 2021年01月  1 2021年02月  5 2021年03月  7 2021年04月  4 2021年05月  4 2021年06月  1 2021年07月  7 2021年08月  2 2021年09月  8 2021年10月  9 2021年11月  16 2021年12月  14 2022年01月  7 2022年05月  1 2022年08月  3 2022年09月  2 2022年10月  2 2022年12月  5 2023年01月  3
标签
算法基础 linux 前端 c++ 数据结构 框架 数据库 计算机基础 储备知识 java基础 ASM 其他 深入理解java虚拟机 nginx git 消息中间件 搜索 maven redis docker dubbo vue 导入导出 软件使用 idea插件 协议 无聊的知识 jenkins springboot mqtt协议 keepalived minio mysql ensp 网络基础 xxl-job rabbitmq haproxy
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。