asm生成for循环语句方法

硅谷探秘者 2333 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基础 2423 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基础 3595 asm动态类和getandset1.自定义类加载器packageclub.jiajia.test;publicclassMyClassLoaderextendsClassLoader
java基础 2941 asm实例对象的调用1.需要的jar包2.我们需要通过asm的目标类如下:packageclub.jiajia.test3;publicclassExamp5
数据库基础 2173 两种用:简单case函数casesexwhen'1'then'男'when'2'then'女’else'其他'endcase搜索函数casewhensex='1'then'男'whensex='2
java基础 1248 ,跳出体等功能。而在结构化程序言中一般不主张使用goto,以免造程序流程的混乱,使理解和调试程序都产困难。但是在java言中,goto这个词只是作为了保留字,还没有使用。那是因为java
数据结构与算法 1629 约瑟夫问题描述有m个人,围一个,编号为1、2、3、、、m,从第一个人开始报数(从1开始数),假设数到n的那个人出局,然后从下一个人继续数数(从1开始数),数到n出列,以此,最后那个人为
weblog 2140 java使用原jdbc连接数据库获取数据或执行sql(mysql) publicvoidtest2(){ try{ //加载MySql的驱动类 Class.forName
数据库 2443 mysql批量更新不同的uuidsql:UPDATEusersetuuid=UUID();去掉中间的-UPDATEusersetuuid=REPLACE(uuid,"-","");注意这两个
归档
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 2023-02  1 2023-03  4 2023-04  2 2023-06  3 2023-07  4 2023-08  1 2023-10  1 2024-02  1 2024-03  1 2024-04  1
标签
算法基础 linux 前端 c++ 数据结构 框架 数据库 计算机基础 储备知识 java基础 ASM 其他 深入理解java虚拟机 nginx git 消息中间件 搜索 maven redis docker dubbo vue 导入导出 软件使用 idea插件 协议 无聊的知识 jenkins springboot mqtt协议 keepalived minio mysql ensp 网络基础 xxl-job rabbitmq haproxy srs 音视频 webrtc javascript
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。