怎么做好营销型网站,工程公司名字,phpcms漏洞,基本建设工程兵网站目录 一、说明二、图解2.1 代码示例2.2 javap操作 三、图示3.1 bipush 153.2 istore_13.3 bipush 83.4 istore_23.5 iload_13.6 iload_23.7 iadd3.8 istore_33.9 return结束 四、附加 一、说明 1.Operand Stack 2.栈可以使用数组或链表来实现 3.每一个独立的栈帧包含一个后进先… 目录 一、说明二、图解2.1 代码示例2.2 javap操作 三、图示3.1 bipush 153.2 istore_13.3 bipush 83.4 istore_23.5 iload_13.6 iload_23.7 iadd3.8 istore_33.9 return结束 四、附加 一、说明 1.Operand Stack 2.栈可以使用数组或链表来实现 3.每一个独立的栈帧包含一个后进先出Last-In-First-Out的操作数栈 4.也可称为表达式栈expression stack 5.操作数栈在方法执行过程中根据字节码指令往栈中写入数据或提取数据即入栈push/出栈pop 6.某些字节码指令将值压入操作数栈其余的字节码指令将操作数取出栈使用它们后再把结果压入栈 7.可以用来执行复制、交换、求和等操作 8.操作数栈主要用于保存计算过程的中间结果同时作为计算过程中变量临时的存储空间 9.操作数栈是jvm执行引擎的一个工作区当一个方法刚开始执行的时候一个新的栈帧也会被创建出来这个方法的操作数栈是空的 10.每一个操作数栈都拥有一个明确的栈深度用于存储数值所需的最大深度在编译器定义好了保存在方法的code属性为max_stack的值 11.栈中的任何一个元素都是可以任意的java数据类型32bit的类型占用一个栈单位深度64bit的类型占用两个栈单位深度 12.操作数栈并非采用访问索引的方式来进行数据访问只能通过标准的入栈push和出栈pop操作来完成一次数据访问 13.被调用的方法带有返回值其返回值将会被压入当前栈帧的操作数栈中并更新pc寄存器中下一条需要执行的字节码指令 14.操作数栈中元素的数据类型必须与字节码指令的序列严格匹配这由编译器在编译器期间进行验证同时在类加载过程中的类检验阶段的数据流分析阶段要再次验证 15.java虚拟机的解释引擎是基于栈的执行引擎该栈指的就是操作数栈
二、图解
2.1 代码示例
package com.learning.stack.operand_stack;/*** Author wangyouhui* Description 操作数栈**/
public class OperandStackTest {public static void main(String[] args) {byte i 15;int j 8;int k i j;}
}2.2 javap操作
javap -v OperandStackTest.classClassfile /F:/jdk-learning/jvm/target/classes/com/learning/stack/operand_stack/OperandStackTest.classLast modified 2023-10-22; size 529 bytesMD5 checksum 82f8abcaba4fd78948113a564c4f83a1Compiled from OperandStackTest.java
public class com.learning.stack.operand_stack.OperandStackTestminor version: 0major version: 52flags: ACC_PUBLIC, ACC_SUPER
Constant pool:#1 Methodref #3.#22 // java/lang/Object.init:()V#2 Class #23 // com/learning/stack/operand_stack/OperandStackTest#3 Class #24 // java/lang/Object#4 Utf8 init#5 Utf8 ()V#6 Utf8 Code#7 Utf8 LineNumberTable#8 Utf8 LocalVariableTable#9 Utf8 this#10 Utf8 Lcom/learning/stack/operand_stack/OperandStackTest;#11 Utf8 main#12 Utf8 ([Ljava/lang/String;)V#13 Utf8 args#14 Utf8 [Ljava/lang/String;#15 Utf8 i#16 Utf8 B#17 Utf8 j#18 Utf8 I#19 Utf8 k#20 Utf8 SourceFile#21 Utf8 OperandStackTest.java#22 NameAndType #4:#5 // init:()V#23 Utf8 com/learning/stack/operand_stack/OperandStackTest#24 Utf8 java/lang/Object
{public com.learning.stack.operand_stack.OperandStackTest();descriptor: ()Vflags: ACC_PUBLICCode:stack1, locals1, args_size10: aload_01: invokespecial #1 // Method java/lang/Object.init:()V4: returnLineNumberTable:line 7: 0LocalVariableTable:Start Length Slot Name Signature0 5 0 this Lcom/learning/stack/operand_stack/OperandStackTest;public static void main(java.lang.String[]);descriptor: ([Ljava/lang/String;)Vflags: ACC_PUBLIC, ACC_STATICCode:stack2, locals4, args_size10: bipush 152: istore_13: bipush 85: istore_26: iload_17: iload_28: iadd9: istore_310: returnLineNumberTable:line 9: 0line 10: 3line 11: 6line 12: 10LocalVariableTable:Start Length Slot Name Signature0 11 0 args [Ljava/lang/String;3 8 1 i B6 5 2 j I10 1 3 k I
}
SourceFile: OperandStackTest.java
三、图示
3.1 bipush 15 1.操作数栈和局部变量表一开始是空的 2.pc寄存器记录要操作的指令地址是0 3.byte i 15; 4.byte、short、char、boolean、int都以int型来保存bipush中b表示bytei表示int 5.bipush 15是将15push到操作数栈当中
3.2 istore_1 1.pc寄存器记录要操作的指令地址2 2.istore_1将栈顶的15存到局部变量表索引为1的位置 3.已经转化为int类型了所以用istore 4.非静态方法局部变量表索引为0的位置是this变量因此istore存的是索引为1的位置 5.操作数栈的栈顶出栈后变为空的
3.3 bipush 8
1.pc寄存器记录要操作的指令地址32.把8压入操作数栈的栈顶
3.4 istore_2 1.pc寄存器记录要操作的指令地址5 2.将操作数栈的栈顶数据出栈保存到局部变量表索引为2的位置 3.操作数栈的栈顶数据出栈后变为空
3.5 iload_1 1.pc寄存器记录要操作的指令地址6 2.iload_1将局部变量表中索引为1位置的数据取出压入操作数栈的栈顶
3.6 iload_2 1.pc寄存器记录要操作的指令地址7 2.iload_2将局部变量表中索引为2位置的数据取出压入操作数栈的栈顶
3.7 iadd 1.pc寄存器记录要操作的指令地址8 2.iadd会弹出操作数栈栈顶的数据执行引擎将字节码指令翻译为机器指令从而让cpu计算俩数据的和23 3.iadd将cpu计算的结果23压入操作数栈的栈顶
3.8 istore_3 1.pc寄存器记录要操作的指令地址9 2.istore_3将操作数栈的栈顶数据出栈保存到局部变量表索引为3的位置 3.操作数栈的栈顶数据出栈后变为空
3.9 return结束
四、附加 1.操作数栈从一开始到结束只用到2个空间即最大深度为2即stack2 2.局部变量表最大索引位置为3局部变量表最大长度为4索引为0的位置是this变量即locals4 3.尽量会以最小的范围来匹配push例如byte范围为-128到127在这个范围内的数会用bipush压入操作数栈short范围为-32768到32727当一个整数超过了byte范围但还在short范围内会用sipush压入操作数栈以此类推