汇编与java字节码

问题

搞懂两个数相加的基本原理

汇编实现

参考汇编教程
macOS上的汇编入门

java实现

jvm规范-操作码列表

jvm内存模型

1
2
3
4
5
6
7
8
JVM内存区域
|_线程共享
|_方法区(常量、静态变量、类信息)
|_堆(存放对象的实例)
|_线程私有
|_程序计数器(代码执行到第几行)
|_虚拟机栈(方法的出入栈)
|_本地方法栈(native方法)

两个整数相加

$vim Test.java

1
2
3
4
5
6
7
8
9
10
public class Test {

public static void main(String[] args) {
int a = 3;
int b = 4;
int i = a + b;
System.out.println(i);
}

}

$ javac Test.java
$ javap -c -l Test

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Compiled from "Test.java"
public class Test {
public Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 1: 0

public static void main(java.lang.String[]);
Code:
0: iconst_3 从常量池获取3(int)
1: istore_1 压入操作数栈位置是1
2: iconst_4 从常量池获取4(int)
3: istore_2 压入操作数栈位置是2
4: iload_1
5: iload_2
6: iadd
7: istore_3
8: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
11: iload_3
12: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
15: return
LineNumberTable:
line 4: 0
line 5: 2
line 6: 4
line 7: 8
line 8: 15
}

方法调用

$vim Foo.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public class Foo {
public static void main(String[] args) {
/*boolean flag = true;
if (flag) System.out.println("Hello, Java!");
if (flag == true) System.out.println("Hello, JVM!");*/
A a = new A();
a.setI(10);
int c = a.hashCode();
System.out.println(c);
System.out.println(a.getI());
}

}

class A {
private int i = 0;

public int getI() {
return i;
}

public void setI(int i) {
this.i = i;
}

@Override
public int hashCode() {
return super.hashCode();
}
}

$javac Foo.java

$javap -c -l Foo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Compiled from "Foo.java"
public class Foo {
public Foo();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 1: 0

public static void main(java.lang.String[]);
Code:
0: new #2 // class A 创建对象
3: dup
4: invokespecial #3 // Method A."<init>":()V 调用构造方法
7: astore_1
8: aload_1
9: bipush 10
11: invokevirtual #4 // Method A.setI:(I)V
14: aload_1
15: invokevirtual #5 // Method A.hashCode:()I
18: istore_2
19: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
22: iload_2
23: invokevirtual #7 // Method java/io/PrintStream.println:(I)V
26: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
29: aload_1
30: invokevirtual #8 // Method A.getI:()I
33: invokevirtual #7 // Method java/io/PrintStream.println:(I)V
36: return
LineNumberTable:
line 6: 0
line 7: 8
line 8: 14
line 9: 19
line 10: 26
line 11: 36
}