You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JVM中bipush指令工作原理及整数范围扩展与字节码存储问询

JVM bipush 指令完全解析

我来逐个解答你的问题,尽量用通俗易懂的方式讲清楚:

1. bipush 指令的工作原理

bipush 是JVM专门用来加载小范围整数的指令,核心作用是把一个8位有符号整数(范围:-128 ~ 127)推送到操作数栈的顶部。

执行流程很简单:

  • 它由两部分组成:1字节的操作码(固定为 0x10) + 1字节的立即数(就是你要推送的那个整数)。
  • JVM执行时,先读取紧跟在操作码后的那个字节,然后把这个8位有符号数符号扩展成32位的int值(因为JVM操作数栈上的int都是32位的),最后把这个32位值压入栈顶。

举个例子:如果要把整数 7 推到栈顶,对应的字节码就是 bipush 7,转换成十六进制就是 10 07。

2. 如何通过 bipush 扩展至更大整数?

首先得明确:bipush 本身的能力上限就是-128到127,没法直接用它处理更大的数。不过JVM提供了配套的指令来覆盖更大范围:

  • 如果你需要处理16位有符号整数(范围:-32768 ~ 32767),可以用 sipush 指令。它的结构是1字节操作码(0x11) + 2字节的立即数,能覆盖比bipush大得多的范围。
  • 要是整数超过了16位的范围(比如大于32767或者小于-32768),就得用 ldc 指令了。这个指令会从运行时常量池中加载指定的int常量,把它推到栈顶。比如你要加载100000,字节码会是ldc #<常量池中的索引>,通过常量池来存储大数值。

另外补充一下你提到的 iload:iload 其实是加载局部变量表中的int值,而iconst_m1到iconst_5这些是它的快捷指令,直接把-1到5的常量推栈,不需要额外的立即数,效率更高。如果要加载6到127的整数,用bipush比ldc更直接(不需要依赖常量池)。

3. bipush 如何在字节码中存储指定整数?

bipush 的字节码存储非常紧凑:

  • 第一字节是固定的操作码:0x10(对应bipush)。
  • 第二字节是目标整数的8位有符号补码。比如:
    • 正整数25:二进制补码是00011001,对应十六进制0x19,所以字节码是0x10 0x19。
    • 负整数-5:8位补码是11111011,对应十六进制0xFB,字节码就是0x10 0xFB。
    • 最小的范围值-128:补码是10000000,对应0x80,字节码为0x10 0x80。

JVM在执行时,会自动把这个8位补码扩展成32位的int(高位全部填充符号位),这样就和操作数栈上的int类型匹配了。

内容的提问来源于stack exchange,提问作者Tim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:56:42