5

我知道 iload 接受整数 -1 到 5,但是如何使用 bipush 指令扩展到更高的数字?特定整数如何与字节码一起存储?

4

2 回答 2

9

有几种不同的指令可用于压入整数常量。

最小的是iconst_* 指令。这些只是一个字节,因为该值是在操作码本身中编码的。iconst_1、iconst_2 等是不同的操作码。iconst_5例如将被编码为字节08

注意:iload是用于加载局部变量值的完全不相关的指令。你一定一直在想iconst_*。

接下来是bipush,它可以压入一个介于 -128 和 127 之间的常数。这条指令有两个字节长——第一个字节是操作码,第二个字节是一个有符号的 8 位整数。您甚至可以使用它来推送 -1 到 5 范围内的常量,尽管这样做会在类文件中占用不必要的空间。例如,bipush 5将被编码为10 05. (0x10 是 bipush 的操作码)

接下来是sipush,除了它存储一个 16 位常量而不是 8 位常量之外,它是相同的,因此指令是三个字节长。sipush 的操作码是 0x11,因此sipush 5将被编码为三字节序列11 00 05

您可能想知道如何存储不适合 16 位的整数常量。在这种情况下,编译器在名为常量池的类文件的单独部分中创建条目,然后使用ldcorldc_w指令来引用常量池条目。

于 2018-05-04T05:46:03.193 回答
3

我认为您正在寻找JVMS 的第 2.11 节,它处理指令表示。特别是,它使用明显的顺序:操作码,紧跟其后的是按顺序排列的操作数,大端(与所有 Java 表示一样)。在 的情况下bipush,这将是字节 0x10后跟文字值。

于 2018-05-04T05:32:20.787 回答