Câu trả lời ngắn gọn : Bạn không thể dịch một tập tin thực thi được liên kết. Mặc dù về mặt kỹ thuật là có thể, nhưng rất khó để thực hiện (xem bên dưới). Tuy nhiên , nếu bạn có tệp nguồn lắp ráp (chứa các hướng dẫn và nhãn), thì rất có thể làm được (mặc dù nếu bạn bằng cách nào đó có được nguồn lắp ráp, trừ khi chương trình được viết bằng cách lắp ráp, bạn nên có mã nguồn chương trình gốc là tốt, vì vậy bạn nên bắt đầu biên dịch nó cho các kiến trúc khác nhau để bắt đầu).
Câu trả lời dài :
QEMU và các trình giả lập khác có thể dịch các hướng dẫn một cách nhanh chóng và do đó chạy một tệp thực thi trên máy tính mà nó không được biên dịch. Tại sao không thực hiện bản dịch này trước thời hạn, thay vì trên đường bay để tăng tốc quá trình?
Tôi biết về nguyên tắc có vẻ dễ dàng, nhưng trong thực tế, gần như không thể vì một vài lý do chính. Để bắt đầu, các bộ hướng dẫn khác nhau sử dụng các chế độ địa chỉ phần lớn khác nhau, cấu trúc opcode khác nhau, kích thước từ khác nhau và một số thậm chí không có hướng dẫn bạn cần.
Giả sử bạn cần thay thế hướng dẫn XYZ
bằng hai hướng dẫn khác ABC
và DEF
. Bây giờ bạn đã chuyển tất cả các địa chỉ tương đối / bù trong toàn bộ chương trình từ thời điểm đó trở đi một cách hiệu quả, do đó bạn sẽ cần phân tích và duyệt qua toàn bộ chương trình và cập nhật các điểm bù (cả trước và sau khi thay đổi). Bây giờ, giả sử một trong những điểm bù thay đổi đáng kể - bây giờ bạn cần thay đổi chế độ địa chỉ, có thể thay đổi kích thước của địa chỉ. Điều này một lần nữa sẽ buộc bạn quét lại toàn bộ tệp và tính lại tất cả các địa chỉ, v.v.
Khi bạn viết chương trình lắp ráp, bạn có thể sử dụng nhãn, nhưng CPU thì không - khi tệp được lắp ráp, tất cả các nhãn được tính là vị trí tương đối, tuyệt đối hoặc bù. Bạn có thể thấy tại sao điều này nhanh chóng trở thành một nhiệm vụ không hề nhỏ, và bên cạnh không thể. Thay thế một đơn hướng dẫn có thể yêu cầu bạn phải đi qua các chương trình hàng trăm toàn bộ thời gian trước khi chuyển.
Từ kiến thức lắp ráp có phần hạn chế của tôi, hầu hết các hướng dẫn như MOV, ADD và các hướng dẫn khác nên có thể di chuyển trên các kiến trúc.
Có, nhưng nhìn vào các vấn đề tôi đã nêu ở trên. Kích thước từ của máy thì sao? Địa chỉ dài? Nó thậm chí có cùng chế độ địa chỉ? Một lần nữa, bạn không thể chỉ "tìm và thay thế" hướng dẫn. Mỗi phân đoạn của một chương trình có một địa chỉ được xác định cụ thể. Nhảy tới các nhãn khác được thay thế bằng các địa chỉ bộ nhớ bằng chữ hoặc bù khi chương trình được lắp ráp.
Bất cứ điều gì không có ánh xạ trực tiếp đều có thể được ánh xạ tới một số hướng dẫn khác, vì tất cả các máy đều là Turing Complete. Làm điều này sẽ quá phức tạp? Nó sẽ không hoạt động vì một số lý do tôi không quen thuộc? Nó sẽ hoạt động, nhưng không mang lại kết quả tốt hơn so với sử dụng trình giả lập?
Bạn đúng 100% rằng cả hai đều có thể , và sẽ nhanh hơn rất nhiều . Tuy nhiên, viết một chương trình để thực hiện điều này là vô cùng khó khăn và rất khó khả thi, nếu không phải vì bất cứ điều gì ngoại trừ các vấn đề tôi đã nêu ở trên.
Nếu bạn có mã nguồn lắp ráp thực tế, việc dịch mã máy sang kiến trúc tập lệnh khác sẽ là chuyện nhỏ. Tuy nhiên, bản thân mã máy được lắp ráp , do đó không có nguồn lắp ráp (chứa các nhãn khác nhau được sử dụng để tính toán địa chỉ bộ nhớ), điều đó trở nên vô cùng khó khăn. Một lần nữa, thay đổi một lệnh đơn có thể thay đổi bù đắp bộ nhớ trong toàn bộ chương trình và yêu cầu hàng trăm lượt đi để tính lại địa chỉ.
Làm điều này cho một chương trình với một vài ngàn hướng dẫn sẽ cần hàng chục nếu không phải là hàng trăm ngàn lượt. Đối với các chương trình tương đối nhỏ, điều này có thể khả thi, nhưng hãy nhớ rằng số lần vượt qua sẽ tăng theo cấp số nhân với số lượng hướng dẫn máy trong chương trình. Đối với bất kỳ chương trình có kích thước vừa đủ, gần như không thể.