」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 一些錯誤的解決

一些錯誤的解決

發佈於2024-08-19
瀏覽:763

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