0
0
Lập trình
Admin Team
Admin Teamtechmely

Khắc Phục Lỗi Trong Dự Án Prototype MiniScript 2.0

Đăng vào 5 ngày trước

• 5 phút đọc

Khắc Phục Lỗi Trong Dự Án Prototype MiniScript 2.0

Giới Thiệu

Khi làm việc với các dự án phần mềm, đôi khi bạn sẽ gặp phải những tình huống khó khăn khi tìm kiếm lỗi. Bài viết này sẽ hướng dẫn bạn cách khắc phục một lỗi trong dự án prototype mà Joe Strout đang phát triển cho MiniScript 2.0. Dự án này bao gồm một ngôn ngữ lắp ráp, một trình lắp ráp và một máy ảo (VM) để chạy mã byte đã được biên dịch. Những kết quả benchmark mới nhất rất hứa hẹn, cho thấy MiniScript hoàn toàn có thể bước vào một kỷ nguyên mới của lập trình tốc độ cao.

Cấu Trúc Dự Án

Dự án prototype của MiniScript 2.0 bao gồm:

  • Ngôn ngữ lắp ráp: Cho phép lập trình viên viết mã lắp ráp.
  • Trình lắp ráp: Biên dịch mã lắp ráp thành mã byte.
  • Máy ảo (VM): Chạy mã byte đã được biên dịch.

Tình Huống Gặp Phải

Tôi đã thêm một chương trình lắp ráp mẫu tính giai thừa và hỗ trợ cho các mã lệnh MULT và DIV trong cả trình lắp ráp và VM. Khi Redspark từ Discord MiniScript bắt đầu thêm hỗ trợ cho nhiều mã lệnh so sánh hơn vào VM, tôi cũng đã thêm hỗ trợ cho các mã lệnh này trong trình lắp ráp. Tuy nhiên, khi thử nghiệm với mã lệnh mới, tôi đã gặp phải một lỗi không mong muốn.

Mã Lệnh Kiểm Tra

Tôi đã viết một chương trình lắp ráp để kiểm tra các mã lệnh:

Copy
# Một chương trình kiểm tra các toán tử so sánh.
#  0 -> Hoạt động
# -1 -> Không hoạt động

@main:
    LOAD r0, 0
    LOAD r1, 1

    IFLT r1, r0, error # Kiểm tra <
    IFEQ r0, r1, error # Kiểm tra ==
    IFNE r0, r0, error # Kiểm tra !=
    IFLE r1, r0, error # Kiểm tra <=
    RETURN
error:
    LOAD r0, -1
    RETURN

Chương trình này nên trả về 0, nhưng lại trả về -1, chỉ vì dòng chứa IFEQ. Mã lệnh IFEQ mới được thiết kế để kiểm tra xem hai thanh ghi có bằng nhau hay không, và nếu có, nhảy đến nhãn cho trước. Trong trường hợp này, nó đã nhảy khi mà kết quả rõ ràng là KHÔNG bằng nhau.

Bắt Đầu Tìm Lỗi

Đầu tiên, chương trình lắp ráp rất đơn giản và thực tế là đúng. Tôi đã kiểm tra các thay đổi mã mà tôi đã thực hiện trong trình lắp ráp và không thấy gì sai. Tôi cũng đã kiểm tra các thay đổi của RedSpark trong VM nhưng không thấy vấn đề nào. Tôi quyết định thêm một số câu lệnh in để gỡ lỗi - việc này không phải là cách làm tốt nhất nhưng trong tình huống này, tôi nghĩ rằng không cần quá phức tạp.

Khi thực thi mã, VM đang thực hiện IFLT thay vì IFEQ. Tôi đã xác định hai khả năng:

  1. Trình lắp ráp đang dịch mã lệnh sai.
  2. VM đang thực hiện mã lệnh sai.

Tôi đã kiểm tra lại cả hai thay đổi nhưng vẫn không tìm ra vấn đề. Tôi cần nhiều thông tin hơn.

Phát Hiện Vấn Đề

Điều làm tôi bối rối hơn là các mã lệnh được tạo ra từ trình lắp ráp của tôi là chính xác, nhưng không khớp với những gì mà VM đang thực thi. Tôi đã thêm nhiều dòng in gỡ lỗi hơn trong trình lắp ráp, và bật biến debug trong VM để có thêm thông tin.

Sau khi nhận được đầu ra, tôi đã nhận thấy rằng mã lệnh 7, 9, và 10 được phát ra đúng, nhưng tất cả chúng đều được VM xem như mã lệnh 7 (mã lệnh IFLT, toán tử so sánh gốc). Điều này có nghĩa là tất cả các mã lệnh so sánh đều bị VM chạy như IFLT. Rõ ràng có điều gì đó sai trong quá trình giữa đầu ra của trình lắp ráp và việc thực thi của VM.

Nguyên Nhân Gốc Rễ

Vấn đề xảy ra trong quá trình lượt biên dịch thứ hai của trình lắp ráp. Khi nó chuyển đổi nhãn thành một offset trực tiếp, nó cũng đã ghi đè mã lệnh liên quan đến dòng đó. Phần mã này đảm bảo rằng IFLT là mã lệnh so sánh duy nhất được gửi đi trong quá trình viết lại cuối cùng. Vì IFLT là mã lệnh so sánh duy nhất có trong mã khi phần này của dự án được viết, nên không có hậu quả cho đến khi người ta quyết định bắt đầu thêm nhiều mã lệnh hơn.

Kinh Nghiệm Học Được

Các lập trình viên thường nói rằng lập trình là về việc suy nghĩ ngoài khuôn khổ. Việc gỡ lỗi cũng vậy. Tôi đã bắt đầu với giả định rằng lỗi có thể nằm trong mã mới, nhưng cũng cần xem xét rằng lỗi có thể nằm trong mã hiện có, mà đã giữ những giả định không còn đúng nữa.

Mẹo Khắc Phục Lỗi

  • Kiểm tra lại mã lệnh: Đảm bảo rằng mã lệnh được phát ra từ trình lắp ráp là đúng.
  • Sử dụng gỡ lỗi: Thêm các câu lệnh in gỡ lỗi để tìm hiểu tình huống.
  • Kiểm tra sự thay đổi: Đánh giá các thay đổi trong mã hiện có khi thêm các tính năng mới.

Các Sai Lầm Thường Gặp

  • Giả định rằng mã mới là nguyên nhân duy nhất của lỗi.
  • Bỏ qua việc kiểm tra mã lệnh được phát ra từ trình lắp ráp.

Kết Luận

Tìm kiếm và khắc phục lỗi trong một dự án phần mềm là một phần không thể thiếu trong quy trình phát triển. Hy vọng rằng bài viết này đã cung cấp cho bạn cái nhìn sâu sắc về cách giải quyết vấn đề trong dự án MiniScript 2.0 và giúp bạn áp dụng những kinh nghiệm này vào dự án của riêng mình. Hãy tiếp tục theo dõi chúng tôi để nhận thêm nhiều thông tin hữu ích về lập trình và phát triển phần mềm!

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào