I found this question that answered it for C++:
How do you get assembler output from C/C++ source in gcc?

- 328,167
- 45
- 605
- 847

- 157
- 1
- 2
- 8
-
3Java doesn't output assembly code. – Jun 19 '15 at 02:06
-
3Oh, it does indeed :). Just have a look at https://www.beyondjava.net/blog/java-programmers-guide-assembler-language/ or my answer below. – Stephan Rauh Feb 03 '18 at 16:43
2 Answers
Java uses both bytecode and assembly language machine code. It's a two-step process. The first step is to compile the Java source code to bytecode, as @elliott-frisch pointed out. At runtime, the JVM watches which parts of the program are used a lot. If a method "runs hot", it's compiled to machine code. That, in turn, is a multi-step process itself, including many optimizations and replacing fast code with even faster code. I've described this in BeyondJava.net several years ago.
If you can spare 45 minutes, I also recommend watching the talk of Charles Nutter. "Down the rabbit hole" is a great introduction to how Java compiles to assembly language.
As for your question: you have to add some parameters to the command starting the application:
javaw.exe -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly Adder
You also have to download a special DLL and store it in the jre folder. Also see Chris Newlands article on how to compile this file for OS X.

- 3,069
- 2
- 18
- 37
-
2There's already a [How to see JIT-compiled code in JVM?](https://stackoverflow.com/questions/1503479/how-to-see-jit-compiled-code-in-jvm) Q&A which suggests the same options. – Peter Cordes Feb 23 '18 at 18:12
-
It doesn't compile anything to assembly code. It goes straight to machine code. You can get a printable output in assembly but that's a byproduct of the printing process. Java does not waste its time running an assembler. – user207421 May 08 '22 at 06:49
-
1You're right. I've corrected the text. In my mind assembly code and machine code are sort of synonyms, because when I'm programming on the machine code level, I'm using an assembler. – Stephan Rauh May 22 '22 at 11:10
Java uses bytecode. The most similar would be javap
, per the linked Oracle documentation, the javap command disassembles one or more class files. Its output depends on the options used.
package com.stackoverflow;
class Main {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
If I compile that to Main.class
and then run javap -v Main.class
I get
Classfile /home/efrisch/workspace/StackOverflow/bin/com/stackoverflow/Main.class
Last modified Jun 18, 2015; size 553 bytes
MD5 checksum de4f987e783aa0f145e7245269504028
Compiled from "Main.java"
class com.stackoverflow.Main
minor version: 0
major version: 52
flags: ACC_SUPER
Constant pool:
#1 = Class #2 // com/stackoverflow/Main
#2 = Utf8 com/stackoverflow/Main
#3 = Class #4 // java/lang/Object
#4 = Utf8 java/lang/Object
#5 = Utf8 <init>
#6 = Utf8 ()V
#7 = Utf8 Code
#8 = Methodref #3.#9 // java/lang/Object."<init>":()V
#9 = NameAndType #5:#6 // "<init>":()V
#10 = Utf8 LineNumberTable
#11 = Utf8 LocalVariableTable
#12 = Utf8 this
#13 = Utf8 Lcom/stackoverflow/Main;
#14 = Utf8 main
#15 = Utf8 ([Ljava/lang/String;)V
#16 = Fieldref #17.#19 // java/lang/System.out:Ljava/io/PrintStream;
#17 = Class #18 // java/lang/System
#18 = Utf8 java/lang/System
#19 = NameAndType #20:#21 // out:Ljava/io/PrintStream;
#20 = Utf8 out
#21 = Utf8 Ljava/io/PrintStream;
#22 = String #23 // Hello, World!
#23 = Utf8 Hello, World!
#24 = Methodref #25.#27 // java/io/PrintStream.println:(Ljava/lang/String;)V
#25 = Class #26 // java/io/PrintStream
#26 = Utf8 java/io/PrintStream
#27 = NameAndType #28:#29 // println:(Ljava/lang/String;)V
#28 = Utf8 println
#29 = Utf8 (Ljava/lang/String;)V
#30 = Utf8 args
#31 = Utf8 [Ljava/lang/String;
#32 = Utf8 SourceFile
#33 = Utf8 Main.java
{
com.stackoverflow.Main();
descriptor: ()V
flags:
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 3: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/stackoverflow/Main;
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=1, args_size=1
0: getstatic #16 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #22 // String Hello, World!
5: invokevirtual #24 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
LineNumberTable:
line 5: 0
line 6: 8
LocalVariableTable:
Start Length Slot Name Signature
0 9 0 args [Ljava/lang/String;
}
SourceFile: "Main.java"

- 198,278
- 20
- 158
- 249