2010-04-02 3 views
0

프로그래밍 수업에는 메모리 단위, CPU, 입력, 출력, 명령어 레지스터, 프로그램 카운터, MAR, MDR 등을 포함하는 가상 머신을 만드는 프로젝트가있었습니다. 이제 우리는 일부 txt 편집기로 작성된 .exe 파일을 Java 바이트 코드로 변환하고 코드를 실행하는 Java 코드를 사용하여 컴파일러를 작성해야합니다.Java - 컴파일러 도움말 만들기

IN X 
IN Y 
ADD X 
STO Y 
OUT Y 
STOP 
DC X 0 
DC Y 0 

난 그냥 초보자입니다 만이 쓸 수있는 이일이 매우 손실이고 어디서부터 시작 아무 생각이 : 우리가 .exe 파일에 작성됩니다 코드의 라인을 따라 기계 코드 .... 어떤 도움을 많이 주시면 감사하겠습니다. 고마워요

아무도보고 이해하지 못해요. 분명히 이해할 것입니다 ...... 나는 첫 해에 프로그래밍 과정을 밟았으며, 선생님은 우리가 가상 머신을 만들어서 CPU 용 코드를 게시하게했습니다. Computer Classes하지만 선생님은 매우 조직적이지 않으므로 컴파일러 인 마지막 프로젝트에 시간이 없습니다 ..... 위의 코드는 바이트 코드로 변환 될 코드의 예입니다 ... 여기 내 가상 머신의 패키지에 CPU와 컴퓨터의 코드는 ... 여기

class Cpu{ 
    private MemEl acc; 
    private InstReg ir; 
    private ProgCount pc; 
    private Input in; 
    private OutPut out; 
    private MemEl mdr; 
    private MemEl mar; 
    public Cpu() 
    { 
     pc = new ProgCount(); 
     ir = new InstReg(); 
     acc = new MemEl(); 
    } 
    public Boolean stop() 
    { 
     return ir.getOpcode() == 0; 
    } 
    public int getMAR() 
    { 
     return ir.getOpcode(); 
    } 
    public int getMDR() 
    { 
     return mdr.read(); 
    } 
    public void setMDR(int n) 
    { 
     mdr.write(n); 
    } 
    public boolean OutFlag() 
    { 
     return ir.getOpcode() == 8; 
    } 
    public boolean InFlag() 
    { 
     return ir.getOpcode() == 7; 
    } 
    public boolean StoreFlag() 
    { 
     return ir.getOpcode() == 2; 
    } 
public void fetch() 
    { 
     mar.write(pc.getValue()); 
     pc.plus(); 
    } 
    public void reset() 
    { 
     mar.write(0); 
     pc.write(0); 
     pc.write(1); 
    } 
    public void fetch2() 
    { 
     ir.write(mdr.read()); 
    } 
    public void decode() 
    { 
     mar.write(ir.getOperand()); 
     mdr.write(acc.read()); 
    } 
public void execute() 
    { 

     switch(ir.getOpcode()){ 
     case 0: 
      System.out.println("Complete"); 
      break; 
     case 1: 
      acc.write(mdr.read()); 
      break; 
     case 2: 
      acc.write(ir.getOperand()); 
      break; 
     case 3: 
      acc.write(acc.read() + mdr.read()); 
      break; 
     case 4: 
      acc.write(acc.read() - mdr.read()); 
      break; 
case 5: 
      acc.write(acc.read() * mdr.read()); 
      break; 
     case 6: 
      acc.write(acc.read()/mdr.read()); 
      break; 
     case 7: 
      mar.write(ir.getOperand()); 
      break; 
     case 8: 
      System.out.println(getMDR()); 
      break; 
     case 9: 
      pc.write(getMDR()); 
      break; 
     case 10: 
      if(0 == acc.read()) 
       pc.write(getMDR()); 
      else 
       fetch(); 
      break; 
     case 11: 
      if(0 < acc.read()) 
       pc.write(getMDR()); 
      else 
       fetch(); 
      break; 
     } 

    } 

내 컴퓨터 클래스입니다

import java.io.*; 
class Computer{ 
    private Cpu cpu; 
    private Input in; 
    private OutPut out; 
    private Memory mem; 
    public Computer() throws IOException 
    { 
     Memory mem = new Memory(100); 
     Input in = new Input(); 
     OutPut out = new OutPut(); 
     Cpu cpu = new Cpu(); 
     System.out.println(in.getInt()); 
    } 
    public void run() throws IOException 
    { 
     cpu.reset(); 
     cpu.setMDR(mem.read(cpu.getMAR())); 
     cpu.fetch2(); 
     while (!cpu.stop()) 
      { 
       cpu.decode(); 
       if (cpu.OutFlag()) 
        OutPut.display(mem.read(cpu.getMAR())); 
       if (cpu.InFlag()) 
        mem.write(cpu.getMDR(),in.getInt()); 
       if (cpu.StoreFlag()) 
        { 
         mem.write(cpu.getMAR(),in.getInt()); 
         cpu.getMDR(); 
        } 
       else 
        { 
         cpu.setMDR(mem.read(cpu.getMAR())); 
         cpu.execute(); 
         cpu.fetch(); 
         cpu.setMDR(mem.read(cpu.getMAR())); 
         cpu.fetch2(); 
        } 
      } 
    } 
public void load() 
    { 
     mem.write(0,799); 
     mem.write(1,199); 
     mem.write(2,1009); 
     mem.write(3,398); 
     mem.write(4,298); 
     mem.write(5,199); 
     mem.write(6,497); 
     mem.write(7,299); 
     mem.write(8,902); 
     mem.write(9,898); 
     mem.write(97,0); 
     mem.write(98,0); 
     mem.write(99,1); 
    } 

} 
,

Load 메서드는 기계가 작동하는지 확인하기위한 임시 메서드 일뿐입니다.로드되는 메서드는 컴파일러에서 생성 한 바이트 코드입니다. 당신은 자바 바이트 코드로 뭔가를 변환해야하는 경우

+5

'.exe'는 그러한 파일에 대해 * 약간 * 혼란스러운 확장자입니다. – Thomas

+0

올바른 프로그래밍 수업을 받았다고 확신합니까? 실제로 가상 프로젝트 프로젝트를 수행 했습니까? 아니면 그룹 프로젝트 인 경우 최소한 심각하게 참여 했습니까?어쨌든 명확하지 않은이 할당은 가상 시스템보다 훨씬 쉽게 보입니다. 나는 당신이 자료를 배우고 적용 할 수있을 때만 코스를 듣고 전달하려고 시도 할 것을 제안합니다. –

+0

나는 이해하지 못한다. '.exe' 파일을 어떻게 텍스트 편집기에 쓸 수 있습니까? 또는 지침이 확장명이 .exe 인 파일로 작성된다는 것을 의미합니까? 좋지 않은 선택입니다! –

답변

3

이것은 당신의 질문과 당신이해야 할 시간에 따라 매우 야심적이지만, 나는 당신을 올바른 길로 인도하려고 노력할 것입니다. 분명히 숙제이므로 아무도 대답을주지 않을 것입니다.)

예제의 코드를 더 정확하게 "어셈블리 코드"라고합니다. 이 방법을보십시오. 각 라인에

  • 읽기 최초의 "단어"(명령 또는 운영자)에서
  • 봐와 자바 바이트 코드에 있음을 동일시 : 당신은해야합니다. Look here.
  • 연산자에 대해 얼마나 많은 인수 (피연산자)를 읽어야하는지 파악합니다.
  • 나머지 행에 적절한 피연산자 수가 있는지 확인하십시오.
  • Java 사양에 따라 적절한 순서로 바이트 코드를 작성하십시오.
  • 는 VM에 바이트 코드를로드하고 강사는 아마 당신에게 준 몇 가지 명시 적 규칙이 있습니다 것처럼

귀하의 예제의 어셈블리 코드가 보이는 실행합니다. 예를 들어, "ADD X"는 위치 X의 내용을 추가하는 것을 의미합니다. "IN"은 "입력"또는 "증분"을 의미합니까? "STO Y"는 무언가를 위치 Y에 저장한다는 의미입니다. 결과를 담고있는 암시 적 레지스터가있는 것 같습니다. 그것도 강사의 사양의 일부 여야합니다. 행운을 빕니다! 해킹 당하십시오!

0

, 다음 (적어도!)

  1. 자바 바이트 코드 표준을 알아해야! (하지 않는 한이 클래스 발명 모형 자바 바이트 코드는?)
  2. 입력 ".EXE"(안 좋은 확장자 이름 이럴)를 사용하여 구문 분석 있고 StringTokenizer 또는 유사한 클래스
  3. 대안에 대한 쓸 무엇을 결정하기 위해 어휘 분석기를 사용 코드.
  4. 포맷 출력은 자바 바이트 코드 '표준

그리고 "그게 관하여"에 대한 책을 읽은에서 배운 것을 사용 -하지만 프로젝트가 좀 더 많은 시간을 사용할 수처럼 매우 경험이하지 않는 한, 사운드 이 주제에 ...

+0

사실, 이전 프로젝트를 수행했거나 상당히 기여한 사람이라면 수 시간 만에 과제를 수행 할 수있었습니다 .CPU 시뮬레이터는 대용량 프로젝트이며, 실제 어셈블러는 그렇게 빨리 작성하는 것이 부당합니다. –

+0

그래,하지만 그것에 대해 예의 바르고 싶습니다. –

0

내가 제대로을 understoond 경우에, 당신은해야합니다

  • 는 어휘 분석기를 만들 수 있습니다. 주어진 텍스트의 경우, 어휘의 순서를 만든다.
  • 구문 분석기를 만듭니다. 그것은 구문 트리를 생성합니다.
  • 트리를 거쳐 코드를 생성하는 인터프리터를 작성하십시오.
  • 이 생성 된 코드를 실행하는 VM을 만듭니다.
1

초보자이고 이틀 동안 컴파일러를 쓸 수 있습니까?

와우. 너의 성은 "크 누스"가되기를 바랍니다.

반드시 this을 읽었어야합니다. 링크 중 하나는 a list of Java bytecode instructions입니다.

"기계어"파일 지침이 어떻게 매핑되는지 알아야합니다. "DC"는 "이중 비교"와 동일한가요? 그렇다면 dcmpg (16 진수 98) 또는 dcmpl (16 진수 98)입니까? 등등.

심각하게? 행운을 빕니다.

1

이 코드는 작성하려고하는 Java 바이트 코드라고 생각하지 않습니다. 이것은 실제로 특정 CPU의 바이트 코드입니다. 이렇게하면 프로젝트가 크게 단순 해집니다. 이것은 또한 스택 아키텍처를 가지고있는 것처럼 보이므로 단일 피연산자 만 가질 수 있습니다.

입력 내용이 텍스트이고 사용자 정의 CPU에 정의 된 어셈블리 언어 만 있기 때문에 텍스트를 아주 쉽게 읽고 구문 분석 할 수 있어야하며 이진 코드를 작성할 수 있어야합니다. 다음은 도움이되는 몇 가지 의사 코드입니다.

initialize Map of instruction names (keys) to instruction op codes (ByteCodeInfo); 
initialize empty bytecode-operations list; 
open input text file; 
while (more to read) 
{ 
    read next line; 
    split line by spaces; 
    lookup ByteCodeInfo in the Map; 
    if (num actual operands != num expected operands - from ByteCodeInfo) 
     throw exception(parse failed on line ####); 
    add new operation to list of operations (each element in the list is an address) 
    if there is a variable reference (e.g. "X") add this to a symbol Map; 
    if this is a variable declaration (DC...) update the symbol object with the address; 
} 
close input text file; 

open output binary file (the byte-code file); 
for each element in operation list 
{ 
    write address, byte-code, operands (if any); 
} 
close byte-code file; 

당신은 당신의 저장 주소를 추적해야합니다 및 명령

해결이 그렇게 용기를 가지고 불가능한 일이 아니다 그것을 당신이 경험이있는 경우, 하루 정도이 작업을 수행 할 수 있습니다 다른 수업을 만드는 것과

편집 : 같은이 클래스는 또한에 따라 바이트 코드를 방출하는 데 사용할 수 등 ID, 피연산자의 수, 피연산자의 예상 유형, 같은 바이트 코드에 대한 정보를 나타냅니다 추가 ByteCodeInfo 클래스 구문 분석 된 행 정보. 이것은 더 나은 추상화를 제공 할 것이고 원래의 제안대로 Map에 opcode int를 저장합니다.