asm生成for循环语句方法

硅谷探秘者 738 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基础 1045 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基础 1972 asm动态类和getandset1.自定义类加载器packageclub.jiajia.test;publicclassMyClassLoaderextendsClassLoader
java基础 1543 asm实例对象的调用1.需要的jar包2.我们需要通过asm的目标类如下:packageclub.jiajia.test3;publicclassExamp5
java基础 162 ,跳出体等功能。而在结构化程序言中一般不主张使用goto,以免造程序流程的混乱,使理解和调试程序都产困难。但是在java言中,goto这个词只是作为了保留字,还没有使用。那是因为java
数据库基础 1187 两种用:简单case函数casesexwhen'1'then'男'when'2'then'女’else'其他'endcase搜索函数casewhensex='1'then'男'whensex='2
数据结构与算法 222 约瑟夫问题描述有m个人,围一个,编号为1、2、3、、、m,从第一个人开始报数(从1开始数),假设数到n的那个人出局,然后从下一个人继续数数(从1开始数),数到n出列,以此,最后那个人为
weblog 293 java使用原jdbc连接数据库获取数据或执行sql(mysql) publicvoidtest2(){ try{ //加载MySql的驱动类 Class.forName
weblog 38 冠词-英
归档
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月  4
标签
算法基础 linux 前端 c++ 数据结构 框架 数据库 计算机基础 储备知识 java基础 ASM 其他 深入理解java虚拟机 nginx git undefined undefined sdf sdf dsdf sdfasdfasd sdf ppp sdf fggdgsd kkk kkk kkk sdddf 456
目录