2012-01-16 47 views
4

我正在按照傑克Crenshaw在http://compilers.iecc.com/crenshaw找到的優秀讓我們建立一個編譯器教程。我正在用Easy68k http://www.easy68k.com/ 68000編輯器/彙編程序/模擬器測試生成的68k程序集。我已經進入第2部分http://compilers.iecc.com/crenshaw/tutor2.txt,但分隔程序對我來說工作不正常。鴻溝(DIVS)不工作傑克crenshaw的讓我們建立一個編譯器

... 
{ Recognize and Translate a Divide } 
procedure Divide; 
begin 
    Match('/'); 
    Factor; 
    EmitLn('MOVE (SP)+,D1'); 
    EmitLn('DIVS D1,D0'); 
end; 
... 

如果我輸入「8/2」作爲測試,那麼編譯器生成以下代碼:

MOVE #8,D0 
MOVE D0,-(SP) 
MOVE #2,D0 
MOVE (SP)+,D1 
DIVS D1,D0 

這在我看來,它實際上是計算2/8(即它的錯誤的方式),因爲在D0中剩下的值是00020000.我可以通過將最後一行重寫爲DIVS D0,D1來解決這個問題,但是這會將結果留在D1中而不是其他例程中的D0,並且對我來說似乎不太可能這樣一個開創性的工作將是不正確的。我搜查了互聯網,但我看不到其他人遇到過這個問題。所以這是否意味着: 1)我做錯了 - 可能 2)傑克做錯了 - 不太可能 3)Easy68k模擬器做錯了 - 不太可能 然而,我只是不明白我做錯了什麼。 請幫忙。

回答

7

我想我可能已經破解了它。本教程http://compilers.iecc.com/crenshaw/tutor3.txt第3條有一個稍微不同的版本鴻溝的過程中,雖然似乎解釋也許這是一個錯字不..第三條在修訂後的版本是

{ Recognize and Translate a Divide } 
procedure Divide; 
begin 
    Match('/'); 
    Factor; 
    EmitLn('MOVE (SP)+,D1'); 
    EmitLn('EXS.L D0'); 
    EmitLn('DIVS D1,D0'); 
end; 

注意添加該行

EmitLn('EXS.L D0'); 

似乎打算交換寄存器D0和D1的內容。現在雖然Easy68k似乎並不喜歡「EXS.L D0」,檢查Easy68文檔後,我改變了這個閱讀

EmitLn('EXG D0,D1'); 

現在的鴻溝過程工作。我不確定這是否是Easy68k特有的,或者爲什麼這篇文章說EXS.L,但現在至少可以工作。歡呼!