簡體   English   中英

理解 Hack 匯編語言代碼

[英]Understanding Hack Assembly Language code

我的老師給了我這個示例代碼來學習,我仍然不明白,與匯編語言代碼和nand2tetris有關。 有人可以解釋嗎?

這些是我還沒有完全理解的部分:

                @R1 
                D=M //Load RAM[1] into D register
                @x  
                M=D
            
        (While loop)
                @x  
                D=M 
                @END
                D;JLE //if x <= 0, jump to END: how do you know x is <= 0 here? Also, what does the 'D;' mean?
         

        //some random codings in the middle...


        (End loop)  
                @END  //When jump to end,
                0;JMP //Infinite loop (program ends) -Is it like the '0;' here specifies that if x <= 0
    

--> 謝謝,也許有不同的解釋我就能得到它:“)我還是個新手,請多多包涵

至少有 3 個級別可以理解此類代碼:

  1. 每個單獨的指令做什么(每行匯編)? 這些在教程文本中進行了解釋,但大多數指令只是將一些數據從一個寄存器或 memory 位置或直接到另一個寄存器(或 memory 位置)的指令移動。 他們中的一些人計算而不是/不僅僅是移動數據,例如將兩個東西加在一起。 這些在處理器的 state 中完成微小的變化,並且需要指令序列來完成任何重要的事情。 不過,我們需要了解這些最原始的操作才能遵循程序。

  2. 最基本的操作(我們會在高級語言中看到)是如何執行的。 所有的匯編語言都對循環和 if-then-else 等控制結構使用某種形式的 if-goto-label。 if-goto-label 形式是說“如果這是真(或假),則將指令 stream 更改為該其他位置的其他序列,但如果它為假(或真),則繼續執行當前,順序指令流”。 條件分支通常涉及諸如“if a > b then goto Label;”之類的結構。 所以所有處理器都可以做到這一點,但是這樣的條件涉及到很多操作數,所以很多處理器將它們分成幾條指令。 (a,b 是操作數,> 是另一個,因為有許多不同的關系運算符,然后 Label 是另一個操作數;這是 4 個操作數,通常在一條指令中可以完成的操作不止一個,因此指令集將這些操作分為兩個或更多指令,所以每個只有 2 個操作數左右。)

  3. 然而,在更高的層次上,我們如何使用這些原語完成諸如 while 循環、if-then-else、for 循環和計算表達式之類的控制結構。


在 nand2tetris 中,有兩大類指令。 在匯編語言中用@ 標記的那些會加載帶有地址的A 寄存器。 如何使用它取決於隨后的說明。 @表格以操作數為label,但該ZD304BA20E96D874115888888888888880E34Z可以是代碼ZD304BA20EBA20EE96DBAESTER TOMESTEMENEMENIBER PROPHEN EREMENIBER PROPREMER PROPREMER PROPREMER PROPREMER PROPREMER PROPREMER PROPREMER PROPREMER PROPREMERITYENYENYENYEN88484848484844444444444440404040404040004000400 不以@ 開頭的那些是計算性的,可以在寄存器之間移動數據、加法或減法,以及將數據從 memory 移動到寄存器或以其他方式移動。

在最原始的級別,通過將 label 目標加載到 A 寄存器中來完成條件分支,然后執行一些計算測試和分支,這將有條件地轉移指令 stream 的控制,通過加載程序計數器,或者使用A寄存器與否!


所以,前兩條指令序列說:用 R1 的地址加載 A 寄存器,然后下一條指令說,用 A 處 memory 的值加載 D。在那里,D=M 表示 D 寄存器獲取 M 的值, Memory,其中隱含的意思是 memory 在 A 或內存 [A]。

另外兩條指令序列:@END... D;JLE 說,將 label END 的地址加載到 A 中,然后有條件地跳轉到該指令序列,如果 D <= 0。因此,處理器將有條件地執行 PC=A (或不)。

最后兩條指令序列表示總是跳轉到 label END,大概就在那里,所以程序以一個什么都不做的無限循環結束,這是在簡單處理器上結束程序的常用方法。

用法 @x 是對標記為 x 的數據單元格/位置的引用。 M=D 表示寫入 memory,D=M 表示從 memory 讀取。 因此,有一個名為 x 的變量,它有時會更新,有時會查詢。

至於while循環,它正在做類似的事情

if ( x <= 0 ) goto END;

為了完成這個條件測試和分支,首先將數據 label x 的地址加載到 A,然后 memory 在那里訪問/讀取並加載到 D (D=M); 接下來將代碼label END的地址加載到A中。因此,當D;JLE執行時,D保存了x中值的副本,通過JLE進行測試,並且A保存了END的地址,該地址被傳輸當條件成立時(即 D <= 0)發送到 PC(PC=A)。


這種條件分支可能是 while 循環的一部分,如下所示:

while ( x > 0 ) {
    <loop-body>
}

將轉換為 if-goto-label 形式,如下所示:

Loop1Top:
    if ( x <= 0 ) goto Loop1End;
    <loop-body>
    goto Loop1Top;
Loop1End:

您可以看到 C 和程序集 if-goto 的條件是相反的,因為它們的意義/含義是相反的:在 C 中,while 的循環條件表示何時留在循環中,而在匯編中我們告訴處理器何時停止退出循環,以便測試相反的條件。

我們沒有看到程序的 rest,所以這只是有根據的推測。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM