我们来看一下这样一段逻辑(Java实现)
代码语言:javascript复制public void print(int i,int j) {
int f;
if (i == j) {
f = i j;
}else {
f = i - j;
}
}
编译后的字节码
代码语言:javascript复制 public void print(int, int);
descriptor: (II)V
flags: ACC_PUBLIC
Code:
stack=2, locals=4, args_size=3
0: iload_1 //将局部变量表第一个整型变量i入栈
1: iload_2 //将局部变量表第二个整型变量j入栈
2: if_icmpne 12 //将操作数栈的两个整型变量弹出并进行相等比较,如果不相等则跳到位置为12的地方
5: iload_1 //如果相等,将局部变量表第一个整型变量i入栈
6: iload_2 //如果相等,将局部变量表第二个整型变量j入栈
7: iadd //将操作数栈的两个整型变量弹出,并相加后将结果入栈
8: istore_3 //将相加的结果从栈顶弹出并赋值给局部变量表的第三个整型变量f
9: goto 16 //跳转到位置16
12: iload_1 //如果不相等,将局部变量表第一个整型变量i入栈
13: iload_2 //如果不相等,将局部变量表第二个整型变量j入栈
14: isub //将操作数栈的两个整型变量弹出,并相减后将结果入栈
15: istore_3 //将相减的结果从栈顶弹出并赋值给局部变量表的第三个整型变量f
16: return
LineNumberTable:
line 7: 0
line 8: 5
line 10: 12
line 12: 16
LocalVariableTable:
Start Length Slot Name Signature
9 3 3 f I
0 17 0 this Lcom/guanjian/calculate/test/Calc;
0 17 1 i I
0 17 2 j I
16 1 3 f I
其汇编语言如下
代码语言:javascript复制bne $r3,$r4,ELSE //判断r3寄存器与r4寄存器是否相等,如果不等跳转到ELSR标记处
add $r5,$r3,$r4 //如果相等,则将r3寄存器和r4寄存器相加将结果放入r5寄存器
j EXIT //跳转到EXIT标记处
ELSE:
sub $r5,$r3,$r4 //如果不相等,则将r3寄存器和r4寄存器相减将结果放入r5寄存器
EXIT:
通过比较,其实也能看出来,Java字节码的入栈操作其实也就是放入寄存器中,出栈也就是清理寄存器。
Java代码
代码语言:javascript复制public void print() {
int sum = 0;
for (int i = 0;i < 100;i ) {
sum = i;
}
}
编译后的字节码
代码语言:javascript复制public void print();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=1
0: iconst_0 //入栈整数0
1: istore_1 //将栈顶0弹出并赋值给局部变量表第一个整型变量sum
2: iconst_0 //入栈整数0
3: istore_2 //将栈顶0弹出并赋值给局部变量表第二个整型变量i
4: iload_2 //将局部变量表第二个整型变量i入栈
5: bipush 100 //入栈100
7: if_icmpge 20 //将操作数栈的两个值弹出并判断i是否小于100,如果不小于100跳转到位置20
10: iload_1 //将局部变量表第一个整型变量sum入栈
11: iload_2 //将局部变量表第二个整型变量i入栈
12: iadd //将操作数栈的两个整型变量弹出并相加后将结果入栈
13: istore_1 //将栈顶的结果弹出并赋值给局部变量表第一个整型变量sum
14: iinc 2, 1 //将局部变量表的第二个整型变量i自增1
17: goto 4 //跳转到位置4
20: return
LineNumberTable:
line 6: 0
line 7: 2
line 8: 10
line 7: 14
line 10: 20
LocalVariableTable:
Start Length Slot Name Signature
4 16 2 i I
0 21 0 this Lcom/guanjian/calculate/test/Calc;
2 19 1 sum I
其汇编语言为
代码语言:javascript复制addi $s3,$zero,0 //0加上一个常数寄存器zero(里面的数就是0)存入s3寄存器int sum = 0;
addi $s4,$zero,0 //0加上一个常数寄存器zero(里面的数就是0)存入s4寄存器int i = 0
addi $s5,$zero,100 //100加上一个常数寄存器zero(里面的数就是0)存入s5寄存器100
LOOP:
beq $s4,$s5,EXIT //比较s4寄存器的值是否小于S5寄存器的值,如果如果结果为假跳转到EXIT标记i < 100
add $s3,$s4,$s3 //将s4寄存器和s3寄存器的值相加存入s3寄存器sum = i;
addi $s4,$s4,1 //将s4寄存器的值加1存入s4寄存器i
j LOOP //跳转到LOOP标记
EXIT: