[Java] 用图形化界面演示 iadd, isub, iconst_<i> 指令的效果

背景

java\text{java} java 虚拟机支持的字节码指令数超过 200200 200。大多数字节码指令所做的事情是很直观的(例如用于执行算术运算的指令)。如果可以看到指令的执行效果,也许能帮助我们理解对应的指令。我们先从几个简单的指令入手,用图形化界面展示它们的执行效果。本文会提供代码,展示以下指令的执行效果

  • iadd
  • isub
  • iconst_<i> 这是一组指令,它包含以下 77 7 个指令
    • iconst_m1
    • iconst_0
    • iconst_1
    • iconst_2
    • iconst_3
    • iconst_4
    • iconst_5

正文

指令介绍

iadd 指令

iadd 页面介绍了 iadd 指令的作用 ⬇️

这个指令会对操作数栈 (Operand Stack)栈顶的两个元素执行出栈操作,再对这两个元素的和执行入栈操作。

isub 指令

isub 页面介绍了 isub 指令的作用 ⬇️

这个指令会对操作数栈 (Operand Stack)栈顶的两个元素执行出栈操作,再对这两个元素的差(原本更接近栈底 的元素是 value1 value_1 value1,另一个元素是 value2 value_2 value2,那么差值为 value1−value2 value_1 - value_2 value1−value2)执行入栈操作。

iconst_<i> 指令

iconst_<i> 是一组指令,它包含以下 77 7 个指令

  • iconst_m1
  • iconst_0
  • iconst_1
  • iconst_2
  • iconst_3
  • iconst_4
  • iconst_5

iconst_<i> 页面介绍了这些指令的作用 ⬇️

这些指令会对操作数栈 (Operand Stack)执行入栈操作(入栈的值是 −1,0,1,2,3,4,5-1,0,1,2,3,4,5 −1,0,1,2,3,4,5 中的某一个)。

代码实战

我们已经有了足够的理论知识,现在可以写代码进行实战了。我是先找豆包,帮我生成了初版的代码,然后在 trae 的协助下,又做了不少调整,最终的代码是这样的 ⬇️ (请将代码保存为 OperandStackVisualizer.py\text{OperandStackVisualizer.py} OperandStackVisualizer.py

python3 复制代码
import tkinter as tk
from tkinter import ttk, messagebox

class OperandStackVisualizer:
    def __init__(self, root):
        self.root = root
        self.root.title("Operand Stack Visualizationizer")
        self.stack = []  # 栈数据

        # 界面样式
        self.frame = ttk.Frame(root, padding=20)
        self.frame.pack()

        # 画布:用来画栈的方块
        self.height = 500
        self.canvas = tk.Canvas(self.frame, width=300, height=self.height, bg="white")
        self.canvas.grid(row=0, column=0, columnspan=3, pady=10)

        # 按钮
        ttk.Button(self.frame, text="iconst_m1", command=lambda: self.push(-1)).grid(row=1, column=0, padx=5)
        ttk.Button(self.frame, text="iconst_0", command=lambda: self.push(0)).grid(row=1, column=1, padx=5)
        ttk.Button(self.frame, text="iconst_1", command=lambda: self.push(1)).grid(row=1, column=2, padx=5)
        ttk.Button(self.frame, text="iconst_2", command=lambda: self.push(2)).grid(row=2, column=0, padx=5)
        ttk.Button(self.frame, text="iconst_3", command=lambda: self.push(3)).grid(row=2, column=1, padx=5)
        ttk.Button(self.frame, text="iconst_4", command=lambda: self.push(4)).grid(row=2, column=2, padx=5)
        ttk.Button(self.frame, text="iconst_5", command=lambda: self.push(5)).grid(row=3, column=0, padx=5)
        ttk.Button(self.frame, text="iadd", command=self.add).grid(row=3, column=1, padx=5)
        ttk.Button(self.frame, text="isub", command=self.sub).grid(row=3, column=2, padx=5)

        # 初始绘制
        self.update_stack()

    # ------------------------ 栈操作 ------------------------

    def push(self, value):
        self.stack.append(value)
        self.update_stack()

    def add(self):
        if (len(self.stack) < 2):
            messagebox.showwarning("警告", "栈中元素不足2个,无法执行加法操作!")
            return
        value2 = self.stack.pop()
        value1 = self.stack.pop()
        self.stack.append(value1 + value2)
        self.update_stack()

    def sub(self):
        if (len(self.stack) < 2):
            messagebox.showwarning("警告", "栈中元素不足2个,无法执行减法操作!")
            return
        value2 = self.stack.pop()
        value1 = self.stack.pop()
        self.stack.append(value1 - value2)
        self.update_stack()

    # ------------------------ 图形化刷新栈 ------------------------
    def update_stack(self):
        self.canvas.delete("all")
        block_width = 100
        block_height = 50
        x = 100

        # 从下往上画栈(最下面是栈底)
        for i, val in enumerate(self.stack):
            y = self.height - (i+1)*block_height - 10
            self.canvas.create_rectangle(x, y, x+block_width, y+block_height,
                                         fill="#87CEEB", outline="black", width=2)
            self.canvas.create_text(x+block_width/2, y+block_height/2, text=val)

# ------------------------ 启动程序 ------------------------
if __name__ == "__main__":
    root = tk.Tk()
    app = OperandStackVisualizer(root)
    root.mainloop()

使用如下命令可以运行

bash 复制代码
python3 OperandStackVisualizer.py

最开始看到的是空的操作数栈 ⬇️

我们可以通过点击以下按钮来向栈中添加元素

  • iconst_m1
  • iconst_0
  • iconst_1
  • iconst_2
  • iconst_3
  • iconst_4
  • iconst_5

我随便添加了几个元素 ⬇️

此时如果点击 iadd 按钮,栈顶的 33 3 和 44 4 就会出栈,它们的和(即, 77 7)会入栈 ⬇️

此时如果点击 isub 按钮,栈顶的 77 7 和 22 2 就会出栈,它们的差(即, 2−7=−52-7=-5 2−7=−5)会入栈 ⬇️

参考资料

相关推荐
IT_陈寒1 小时前
Vue这个动态响应坑把我整不会了
前端·人工智能·后端
AskHarries1 小时前
做国内还是出海
后端
J2虾虾1 小时前
Spring AI Alibaba文档
java·人工智能·spring
YikNjy2 小时前
break和continue
java·开发语言·算法
春日见2 小时前
五分钟入门 强化学习---DQN(Deep Q Net)算法与实现
人工智能·python·深度学习·算法·microsoft·机器学习
SomeOtherTime2 小时前
Geojson相关(AI回答)
java·前端·python
日月云棠2 小时前
10 Integer —— 最常用的整数包装类深度解析
java·后端
大鸡腿同学2 小时前
大模型为何总 “胡说八道”?做完 RAG 知识库,我看懂了它的底层逻辑
后端
秋92 小时前
java项目中cpu飙升排查及解决方法
java·开发语言