2012-01-16 5 views
4

Jack Crenshaw의 우수 컴파일러 자습서를 작성했습니다 (http://compilers.iecc.com/crenshaw). Easy68k http://www.easy68k.com/ 68000 편집기/어셈블러/시뮬레이터를 사용하여 생성 된 68k 어셈블리를 테스트하고 있습니다. 나는 2 부에 http://compilers.iecc.com/crenshaw/tutor2.txt을 가지고있다. 그러나 나누기 절차가 나를 위해 제대로 작동하지 않는다. 테스트로 I 입력 "8/2"는, 다음 컴파일러는 다음 코드를 생성하는 경우Divine (DIVS) 잭에서 작동하지 않습니다. crenshaw 's가 컴파일러를 빌드 합니다.

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

:

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

이 실제로 2/8 (즉 그것은이다 계산하는 나에게 보인다 잘못된 방법 라운드) 이후에 D0에 남아있는 값이 00020000입니다. DIVS D0, D1로 마지막 줄을 다시 작성하여이 문제를 해결할 수 있지만 다른 루틴에 따라 D0보다는 D1에 결과를 남겨 둡니다. 그러한 정액 작업은 부정확 할 것이다. 나는 인터넷을 수색했지만 다른 누구도이 문제를 보지 못했다. 그래서 그 뜻 : 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; 

참고입니다 레지스터 D0 및 D1의 내용을 교환하는 것으로 보이는 것처럼 라인

EmitLn('EXS.L D0'); 

이 추가되었습니다. Easy68k는 "EXS.L D0"를 좋아하지 않는 것 지금 동안의 Easy68 설명서를 확인 후 나는

EmitLn('EXG D0,D1'); 

을 읽고이 변경되었습니다 지금은 분할 절차가 작동합니다. 이 항목이 Easy68k에만 해당되는지, 아니면 EXS.L이라고 쓰여져있는 이유는 확실하지 않지만 적어도 지금은 작동합니다. 만세!