[명령 생 성] 명령 데이터 구조 및 가상 컴퓨터 명령 집합

여기 서 말 하고 자 하 는 명령 은 x86 시스템 구조 에서 의 기계 명령 이 아니 라 가상 컴퓨터 명령 이다.Jerry 가상 컴퓨터 의 디자인 은 매우 복잡 하지 않 습 니 다. 심지어 매우 유연성 이 없어 보 입 니 다. 이것 은 스 택 가상 컴퓨터 입 니 다. 어떠한 레지스터 (명령 카운터 제외) 도 포함 되 지 않 고 모든 명령 은 스 택 을 바탕 으로 합 니 다.문장 마지막 에 완전한 지령 집 을 제시 할 것 이다.지금 먼저 명령 데이터 구 조 를 제시 합 니 다.
typedef enum {
    // ...    ,          
} InstructionCode;

//    COOL      
// segOffset       
// code    
#define memberAbstractInstruction \
    int segOffset;                \
    InstructionCode code; /*******/

//         
struct AbstractInstruction {
    memberAbstractInstruction
};

//       
struct NoParamInstruction {
    memberAbstractInstruction
};

//         
struct IntParamInstruction {
    memberAbstractInstruction
    int param;
};

//         
struct RealParamInstruction {
    memberAbstractInstruction
    double param;
};

//     
// targetIns       
struct JumpInstruction {
    memberAbstractInstruction
    struct AbstractInstruction* targetIns;
};

아마도 당신 은 이상 하 게 생각 할 것 입 니 다. 왜 점프 명령 은 전체 매개 변수의 명령 에 포함 되 지 않 고 단독으로 꺼 내 고 지침 파 라미 터 를 만들어 야 합 니까?이것 이 해석 기 라면 문제 가 크 지 않 지만 포인터 가 바이트 파일 에 저장 하고 메모리 로 되 찾 으 면 고 릴 라 를 고용 하여 Jerry 컴 파일 러 를 두 드 릴 만큼 운 이 좋 지 않다 면 포인터 가 가리 키 는 주 소 는 우리 가 기대 하 는 것 이 아 닐 것 이다.따라서 이곳 의 목표 지령 지침 의 의 미 는 마지막 에 지령 을 쓸 때 정수 편 이 량 으로 변 한다.
    이 단계 에 있 지 않 으 면 모든 명령 의 주 소 를 잘 알 고 정수 로 이 도 메 인 을 저장 하 는 것 은 후기 최적화 를 고려 한 것 이다.그렇지 않 으 면 일부 삭제 무용 명령 의 최적화 로 인해 점프 명령 의 오프셋 이 효력 을 잃 게 될 것 이다.매번 이런 작은 동작 이 점프 명령 의 오프셋 을 다시 계산 하 는 것 을 피하 기 위해 서 방법 은 점프 명령 의 오프셋 을 파일 에 명령 을 쓰기 전의 마지막 관문 에서 확정 하 는 것 이다.확실한 방법 은 명령 의 segOffset 역 차 이 를 계산 하 는 것 입 니 다. 그러면 seg Offset 의 값 도 그때 (조금 전에) 계산 해 야 합 니 다.
 
    방금 말 했 듯 이 가상 컴퓨터 는 스 택 을 바탕 으로 하 는 것 이기 때문에 게 으 름 을 피 울 수 있 는 기 회 를 많이 가 져 왔 다. 예 를 들 어 덧셈 명령 은 그 몇 개의 레지스터 를 가지 고 놀 지 않 아 도 된다.참고 로 Jerry 의 명령 은 대부분 길이 가 정 해 져 있 고 일부 매개 변수 명령 만 명령 의 끝 에 매개 변 수 를 두 고 그들의 길 이 는 다른 명령 보다 길다.
 
    연산 명령
 
 INT_PLUS       팝 업 창 B 스 택 꼭대기 A 와 A + B 를 계산 하여 스 택 에 넣 습 니 다.
 INT_MINUS                                 -
 INT_MULTIPLY                              *
 INT_DIVIDE                                /
 INT_LT                                    <
 INT_LE                                    <=
 INT_EQ                                    ==
 INT_NE                                    !=
 INT_GT                                    >
 INT_GE                                    >=
 
위 에 A 는 차 창고 지붕 이 고, B 창고 꼭대기 이 고 아래 도 그렇습니다.
 
 INT_ASSIGN 팝 업 창 B 스 택 꼭대기 A 와 B 의 값 을 A 가 가리 키 는 주소 에 기록 한 다음 스 택 꼭대기 에 눌 러 넣 습 니 다. B 의 값.
 
실 형 수 에 대응 하 는 명령 세트 가 있 습 니 다.
    REAL_PLUS, REAL_MINUS, REAL_MULTIPLY, REAL_DIVIDE, REAL_ASSIGN,
    REAL_LT, REAL_LE, REAL_EQ, REAL_NE, REAL_GT, REAL_GE
 
    IO 명령 어
 
    READ_INT   스 택 꼭대기 A 를 팝 업 하고 정 수 를 입력 하여 A 가 가리 키 는 주소 에 값 을 넣 습 니 다.
    READ_REAL                   실수
    WRITE_INT  스 택 정수 A 출력 팝 업.
    WRITE_REAL        실수
 
    런 타임 형식 변환
 
      INT_2_REAL 스 택 정수 팝 업, 실수 로 스 택 으로 전환
      REAL_2_INT        실수      정수
 
 
    상수 로드
 
    LOAD_INT  스 택 꼭대기 A 를 팝 업 하고 정 수 를 입력 하 십시오. A 가 가리 키 는 주소 에서 정 수 를 스 택 꼭대기 로 불 러 옵 니 다.
    LOAD_REAL                                            실수
 
    탄창
 
    POP 는 스 택 의 맨 위 에 있 는 지침 을 기 부 를 향 해 접근 하 게 하 는 것 입 니 다. 이것 은 전체 매개 변 수 를 가 진 명령 입 니 다. 매개 변 수 는 팝 업 의 바이트 수 를 설명 합 니 다.
 
 
    상수 로드
 
    CONST_INT  스 택 꼭대기 에 상수 정 수 를 불 러 오 는 것 은 정형 매개 변 수 를 가 진 명령 입 니 다.
    CONST_REAL           실수               실 형
 
    제어 명령
 
    JMP         무조건 점프, 매개 변 수 는 정수 로 오프셋 을 표시 합 니 다.
    JMP_IF_TOP  스 택 꼭대기 정수 A 를 팝 업 하고 A 가 0 이 아니라면 점프 합 니 다. 매개 변 수 는 정수 이 고 오프셋 을 표시 합 니 다.
    JMP_NOT_TOP                      ... 을 위 하여
    END_프로그램 종료 프로그램
 
 
    기타
    NOP 동작 하지 않 음
 
끝나다
typedef enum {
    INT_PLUS, INT_MINUS, INT_MULTIPLY, INT_DIVIDE, INT_ASSIGN,
    INT_LT, INT_LE, INT_EQ, INT_NE, INT_GT, INT_GE,
    REAL_PLUS, REAL_MINUS, REAL_MULTIPLY, REAL_DIVIDE, REAL_ASSIGN,
    REAL_LT, REAL_LE, REAL_EQ, REAL_NE, REAL_GT, REAL_GE,
    INS_NOT,
    READ_INT, READ_REAL, WRITE_INT, WRITE_REAL,
    INT_2_REAL, REAL_2_INT,
    LOAD_INT, LOAD_REAL, POP,
    CONST_INT, CONST_REAL,
    JMP, JMP_IF_TOP, JMP_NOT_TOP,
    NOP, END_PROGRAM
} InstructionCode;

//                  ,            
#define getCodeByIntOp(x) ((x) - PLUS + INT_PLUS)
#define getCodeByRealOp(x) ((x) - PLUS + REAL_PLUS)

//         
#define isNoParamIns(x) (((x) >= INT_PLUS && (x) <= LOAD_REAL) \
                            || NOP == (x) || END_PROGRAM == (x))
//          
#define isIntParamIns(x) (POP == (x) || CONST_INT == (x))
//          
#define isRealParamIns(x) (CONST_REAL == (x))
//      
#define isJump(x) (JMP <= (x) && (x) <= JMP_NOT_TOP)

좋은 웹페이지 즐겨찾기