”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 一些错误的解决

一些错误的解决

发布于2024-08-19
浏览:567

Resolução de alguns bugs

对于那些不遵循 POJ 的人(JVM 上的 Pascal)是一个将 子集 从 Pascal 转换为 JASM 的编译器(Java Assembly),这样我们就可以使用JVM作为执行环境。

在上一篇文章中,我们实现了对 Pascal 的 函数 的支持。

在这篇文章中,我们要讨论一些很酷的事情吗?没那么多哈哈。这次我们只讨论错误:-)

当我们为 JVM 进行编译时,有必要详细说明这个令人难以置信的虚拟机的各个点的功能。因此,我多次详细介绍 JVM 的内部功能及其一些指令(操作码)。

有关通过命令行传递给程序的参数的错误

当我实现变量声明时,我没有注意到这样一个事实:在 JVM 中,main 函数中的第一个变量是 args,一个包含传递给程序的参数的数组。因此,在此 PR 中,我隐式为 args.

保留第一个位置

处理局部和全局变量时的错误

由于测试 Pascal 程序仅包含全局变量,因此我没有注意到 JASM 生成中存在严重错误。当我创建包含全局和局部变量的程序时,我意识到有些事情不对,哈哈。

来自下面的 Pascal 程序:

program global_var_declaration;
var
    globalvar : integer;
begin
    globalvar := 123;
    write (globalvar);
end.

POJ 生成了以下 JASM:

// Code generated by POJ 0.1
public class global_var_declaration {
    public static main([java/lang/String)V {
        ;; globalvar := 123;
        bipush 123
        istore 1

        ;; write (globalvar);
        getstatic java/lang/System.out java/io/PrintStream
        iload 1
        invokevirtual java/io/PrintStream.print(I)V

        return
    }
}

为了尝试找出问题,我创建了一个与上面的 Pascal 程序等效的 Java 程序:

public class GlobalVarDeclaration {
    public static int globalVar;

    public static void main(String[] args) {
        globalVar = 123;
        System.out.println(globalVar);
    }
}

当我反汇编时,我得到以下程序集

 1: public class GlobalVarDeclaration {
 2:     public static globalVar I
 3:
 4:     public static main([java/lang/String)V {
 5:         bipush 123
 6:         putstatic GlobalVarDeclaration.globalVar I
 7:
 8:         getstatic java/lang/System.out java/io/PrintStream
 9:         getstatic GlobalVarDeclaration.globalVar I
10:         invokevirtual java/io/PrintStream.println(I)V
11:
12:         return
13:     }
14: }

此时我注意到声明“public static globalVar I”(第2行)和指令putstatic(第6行)和getstatic(第2行) 9) .所期望的是 POJ 到目前为止使用的指令 astoreistore。阅读 JVM 文档,我意识到 POJ 声明全局变量就好像它们是 JVM 函数的局部变量一样:-D

无论如何,到目前为止,POJ(错误地)使用操作码 aload/iload/astore/ Istore 用于全局变量,但正确的选项是将变量声明为公共变量(如第 2 行所示)并使用 getstatic/putstatic.

因此,这里对代码进行了重构,以便符号表可以处理本地和全局声明。这里代码被重构,以便符号表可以为局部和全局变量生成正确的指令。

JASM 代码生成已在此处进行更改,以处理新的符号表以及在函数或过程结束后清理本地声明。

这样,从下面的 Pascal 程序中:

program GlobalVarDeclaration;
var
    globalvar : integer;
begin
    globalvar := 123;
    write (globalvar);
end.

POJ 现在可以正确生成以下 JASM:

// Code generated by POJ 0.1
public class global_var_declaration {
    public static globalvar I

    public static main([java/lang/String)V {
        ;; globalvar := 123;
        bipush 123
        putstatic global_var_declaration.globalvar I

        ;; write (globalvar);
        getstatic java/lang/System.out java/io/PrintStream
        getstatic global_var_declaration.globalvar I
        invokevirtual java/io/PrintStream.print(I)V

        return
    }
}

后续步骤

在下一篇文章中我们将讨论上下文和嵌套句子。

完整的项目代码

包含项目完整代码和文档的存储库位于此处。

版本声明 本文转载于:https://dev.to/alexgarzao/resolucao-de-alguns-bugs-3a1i?1如有侵犯,请联系[email protected]删除
最新教程 更多>

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3