Các lượt nộp
    Danh sách bài
    Trang chủ
    Báo lỗi

    solution

    Đề bài: [Trình biên dịch] Thông dịch máy thanh ghi mini (register machine)

    Khác với máy ảo dựa trên ngăn xếp, nhiều kiến trúc thực (và mã máy đích của trình biên dịch) dùng thanh ghi (register) để lưu giá trị trung gian. Xét một máy thanh ghi mini có 10 thanh ghi r0,r1,…,r9r0, r1, \dots, r9r0,r1,…,r9 (khởi tạo bằng 0) và con trỏ lệnh (instruction pointer). Chương trình gồm các dòng lệnh, mỗi dòng có thể có nhãn (label) đứng trước dạng nhãn: lệnh ... (nhãn là một dãy chữ/số, phân biệt với lệnh bởi dấu :). Các lệnh hỗ trợ (toán hạng val là hoặc một thanh ghi rX, hoặc một hằng số nguyên):

    • MOV rX, val: gán rX←valrX \gets valrX←val.
    • ADD rX, val / SUB rX, val / MUL rX, val: rX←rX op valrX \gets rX \ \text{op} \ valrX←rX op val.
    • DIV rX, val: rX←rX÷valrX \gets rX \div valrX←rX÷val (chia lấy phần nguyên làm tròn về 0).
    • JMP nhãn: nhảy vô điều kiện tới lệnh có nhãn đó.
    • JZ rX, nhãn: nhảy tới nhãn nếu rX=0rX = 0rX=0.
    • JNZ rX, nhãn: nhảy tới nhãn nếu rX≠0rX \ne 0rX=0.
    • PRINT rX: in ra giá trị hiện tại của rXrXrX.
    • HALT: dừng chương trình.

    Chương trình bắt đầu thực thi từ lệnh đầu tiên (chỉ số 0). Nếu DIV chia cho 0, in thêm dòng ERROR rồi dừng. Nếu chương trình thực hiện quá 200000200000200000 bước mà chưa HALT (vòng lặp không dừng), in thêm dòng TIMEOUT rồi dừng.

    Ví dụ (tính 5!5!5!):

    MOV r0, 1
    MOV r1, 5
    loop: JZ r1, end
    MUL r0, r1
    SUB r1, 1
    JMP loop
    end: PRINT r0
    HALT
    

    in ra 120.

    • Định dạng đầu vào:
      • Dòng đầu tiên chứa số nguyên mmm (1≤m≤10001 \le m \le 10001≤m≤1000) — số dòng lệnh.
      • mmm dòng tiếp theo, mỗi dòng đúng cú pháp mô tả ở trên. Tên nhãn không trùng lệnh và nếu xuất hiện, luôn ở đầu dòng và có dấu : ngay sau.
    • Định dạng đầu ra:

      In ra, mỗi dòng một giá trị, kết quả các lệnh PRINT theo đúng thứ tự thực thi. Nếu có lỗi chia cho 0, thêm dòng ERROR ở cuối; nếu vượt quá 200000200000200000 bước thực thi, thêm dòng TIMEOUT ở cuối.

    Ví dụ:

    Đầu vào:

    8
    MOV r0, 1
    MOV r1, 5
    loop: JZ r1, end
    MUL r0, r1
    SUB r1, 1
    JMP loop
    end: PRINT r0
    HALT

    Đầu ra:

    120
    

    Đầu vào:

    8
    MOV r0, 0
    MOV r1, 10
    loop: JZ r1, end
    ADD r0, r1
    SUB r1, 1
    JMP loop
    end: PRINT r0
    HALT

    Đầu ra:

    55
    

    Đang tải editor...