Hello, ASM -- code generation

Source: Internet
Author: User

Copyright Disclaimer: During reprinting, please use hyperlinks to indicate the original source and author information of the article and this statement
Http://dreamhead.blogbus.com/logs/4007513.html

The ASM mentioned here is not an assembly language, but a framework for operating Java bytecode. For the Java platform, bytecode is its "assembly language". Therefore, the name of ASM is actually a real name. ASM itself is very powerful, and many software and frameworks choose it as the underlying implementation, such as cglib. In this blog, I will focus on its power in code generation.

In the initial stage, Hello world is always a good choice. That is to say, the generated target code is as follows:
Public class asmexample {
Public static void main (string [] ARGs ){
System. Out. println ("Hello, world ");
}
}

In Java, code is organized in the form of classes, and the. Class file is the carrier of bytecode. In contrast to the above Code, we first need a class.
Public class asmmain {
Public static void main (string [] ARGs ){
Classwriter CW = new classwriter (true );
CW. Visit (Opcodes. v1_1, Opcodes. acc_public, "asmexample", null, "Java/lang/object", null );

...

CW. visitend ();
}
}

In the above Code, classwriter is the class used in ASM to generate the bytecode form. Here, we need to set some attributes for the generated class, such as the class name, access level and super class, and the version number required at the bytecode level. The corresponding Java code is as follows:
Public class asmexample {
}

With the class, the next step is the corresponding method. Let's take a look at the basic structure:
Method M = method. getmethod ("Void main (string [])");
Generatoradapter Mg = new generatoradapter (Opcodes. acc_public + Opcodes. acc_static, M, null, null, Cw );
...
MG. returnvalue ();
MG. endmethod ();
First, we set a method signature, including the method name, parameter, and return type. To generate this method, you also need to set the attributes of some methods, such as the access level. Through the CW parameter, the methods are associated with the same type. The corresponding Java code is as follows:
Public class asmexample {
Public static void main (string ARGs []) {
}
}

All we have done before is to set up a static structure. Next, what we want to do is to let the program work.
MG. getstatic (type. GetType (system. Class), "out", type. GetType (printstream. Class ));
MG. Push ("Hello world! ");
MG. invokevirtual (type. GetType (printstream. Class), method. getmethod ("Void println (string )"));

Here, we are actually dealing with JVM commands, so if we are faced with the same assembly, everything is clearly explained step by step.

First, obtain system. Out. We use the getstatic method to obtain the static field from which class and its type. In fact, the result of this command is to push the retrieved field to the stack. Then, we are converting "Hello world !" Also pushed into the stack. Obviously, this is all about preparing for calling methods.

For parameter ("Hello world!" here !") It is easy for us to accept the inbound stack, but why should we send system. Out to the stack? Let me remind you again that we are thinking at the JVM level. Here, method calls are called back to the original form, this hidden in the Java program must also be passed as a parameter in digital display. That is to say, the method call is changed to the following:
Println (system. Out, "Hello world! ");

Complete all tasks and call methods. In Java, method calls require partitioned and instance methods. They have different commands in the Virtual Machine. Here we want to call the instance method, invokevirtual is used here, And the type is specified. If the method is specified, the method can be called. If you want to call the method of the class, that is, the static method, you need to put invokestatic into the array.

Comparing the definitions of invokevirtual and invokestatic APIs, it is not difficult to find that there is no real difference between them. The reason for this is that it is irrelevant to the Java design, it regards the class as a special thing and does not unify it into the object system. If you design a virtual machine for Ruby, this problem can be eliminated, because in ruby, the class method is the instance method of the class object, so that the class things are unified into the object system, no additional distinction is required.

By now, our goal has been fully achieved:
Public class asmexample {
Public static void main (string ARGs []) {
System. Out. println ("Hello world! ");
}
}

After that, we can convert the defined class into bytes, load it to the virtual machine, and run it, or save it to the file. That's what we like.
Byte [] code = CW. tobytearray ();

Dealing with ASM requires us to lower our posture and stand at the command level to think about it. For example, at this level, to implement the Judgment statement, you need to set the label and then perform the corresponding jump. Here there is no loop statement, and you need to use the judgment and jump to create a loop structure. However, in general, it is easy to correspond to Java programs, just as we did above. In-depth Java Virtual Machine (VM) helps us better understand JVM and ASM programs.

There are several helpers that can help us better generate this game by bytecode. Javap, a jdk tool, can be used to disassemble Java bytecode. When we first came into contact with ASM, when we were not very familiar with commands, we could consider writing our own targets into a Java program, compile them, and use "javap-c" to view them, all the instructions are visible, so we can take the medicine. Jad, which provides us with a Java class file decompiled into a Java file, through which we can know whether the generated bytecode is what we want, the Java code that corresponds to the generation process is implemented by the power of Jad.

ASM is very powerful. Here we only introduce the code generation in ASM. In fact, even the work of code generation is not so complete. ASM also provides another generation method. However, it is not as easy to use as the generatoradapter here. It requires more JVM command intelligence, and the advantage is that it is faster.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.