前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java字节码跟真正汇编的比较

Java字节码跟真正汇编的比较

作者头像
算法之名
发布2020-05-28 22:36:18
9210
发布2020-05-28 22:36:18
举报
文章被收录于专栏:算法之名算法之名

我们来看一下这样一段逻辑(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:
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档