首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在java类文件中找到未指定的JVM字节码(0xe2)

在java类文件中找到未指定的JVM字节码(0xe2)
EN

Stack Overflow用户
提问于 2021-01-01 15:27:42
回答 2查看 92关注 0票数 0

我最近正在开发一个可以分析java类文件的程序。在运行程序之后,这是它的输出:

代码语言:javascript
复制
class test_1 {

    public static String a = "Hello World";

    public static void main(String[] args) {
        int j = 0;
        for(int i = 0;i<10;i++) {
            System.out.println(a);
            j = j + j*j +j/(j+1);
        }
    }
}

我得到了一个没有在jvm规范14中指定的字节码0xe2。0xe2做什么??

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-01-01 16:17:35

你的程序输出每一个字节,如果它们是字节码指令,忽略了许多指令都有参数的事实,所以它们是多字节指令。

例如,您的程序错误地输出构造函数如下:

代码语言:javascript
复制
2a: aload_0
b7: invokespecial
00: nop
01: aconst_null
b1: return

但是,如果您运行javap -c test_1.class,您将看到:

代码语言:javascript
复制
0: aload_0
1: invokespecial #1   // Method java/lang/Object."<init>":()V
4: return

冒号之前的数字是偏移量,而不是字节码。如您所见,缺少偏移量2和3,因为invokespecial指令对参数使用了2个字节,这在文档中有如下说明:

格式 专用indexbyte1 indexbyte2 Description 未签名的indexbyte1indexbyte2用于在当前类(§2.6)的运行时常量池(§2.6)中构造索引,其中索引的值为(indexbyte1 << 8) | indexbyte2

当两个字节为0001时,索引为1,因此字节码指令如javap所示:invokespecial #1

如果然后查看常量池输出,您将看到常量#1是methodrefObject的no-arg构造函数。

您的具体问题与字节码a7 ff e2有关,它不是3个指令,而是goto的3字节指令。

格式 goto branchbyte1 branchbyte2 Description 无符号字节branchbyte1branchbyte2用于构造带符号16位分支偏移量,其中分支偏移量为(branchbyte1 << 8) | branchbyte2

意味着ff e2branchoffset = 0xffe2 = -30,这意味着

代码语言:javascript
复制
a7: goto
ff: impdep2
e2: (null)

你的程序应该打印这样的东西:

代码语言:javascript
复制
a7 ff e2: goto -30
票数 1
EN

Stack Overflow用户

发布于 2021-01-01 15:38:26

无法解释多字节操作码。在后藤参考中,格式是:

代码语言:javascript
复制
goto
branchbyte1
branchbyte2

无符号字节branchbyte1和branchbyte2用于构造带符号的16位分支偏移量,其中分支偏移量为(branchbyte1 << 8) _\_\从这个goto指令的操作码地址开始执行该偏移量。目标地址必须是包含此goto指令的方法中指令的操作码的地址。

goto是0xa 7,后面应该是两个字节,表示分支位置,使指令宽3个字节。您的代码忽略了这一点,将1字节解压缩,然后将接下来的2字节视为有效指令,而它们不是。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65530989

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档