Tại sao trình biên dịch sản xuất mã lắp ráp?


19

Ngôn ngữ hội được chuyển đổi sang ngôn ngữ máy bằng trình biên dịch chương trình. Tại sao một trình biên dịch sẽ chuyển đổi ngôn ngữ cấp cao để lắp ráp? Nó có thể chuyển đổi trực tiếp từ ngôn ngữ cấp cao sang mã máy không?

Câu trả lời:


22

Lý do khác để trình biên dịch sản xuất lắp ráp thay vì mã máy thích hợp là:

  • Các địa chỉ tượng trưng được sử dụng bởi các nhà lắp ráp thay vì các địa chỉ máy mã hóa cứng giúp việc di chuyển mã dễ dàng hơn nhiều.
  • Mã liên kết có thể bao gồm các kiểm tra an toàn như kiểm tra loại và điều đó dễ thực hiện hơn với các tên tượng trưng.
  • Những thay đổi nhỏ trong mã máy sẽ dễ dàng được bổ sung bằng cách thay đổi trình biên dịch mã hơn là trình tạo mã.

Tại sao ngôn ngữ lắp ráp lại hiệu quả đến vậy, mặc dù nó cũng được viết bằng tiếng Anh và cách bộ xử lý hiểu nó?
CODERSAM

3
@CODERSAM Hội là một ngôn ngữ chính thức, không phải là ngôn ngữ tự nhiên. Nó rất gần với ngôn ngữ máy. Vì vậy, tranlation không giới thiệu không hiệu quả.
Martin Berger

Khi bạn nói, "rất gần với ngôn ngữ máy", điều đó có nghĩa là gì? Tôi thực sự bối rối với điều này!
CODERSAM

2
@CODERSAM Ý nghĩa chính xác là phức tạp, nhưng một cái gì đó giống như đồng hình trong đại số. Khi bạn dịch, hãy nói "thêm eax, # 2" là cụm x86, bạn có thể dịch nó sang d7f5 (hoặc bất cứ thứ gì khác mà mã op có thể), ngay lập tức, không cần nhìn vào ngữ cảnh, mà không cần thêm bất kỳ nội dung nào. Hội không có sự trừu tượng.
Martin Berger

1
"Hội không có sự trừu tượng hóa" - Tôi muốn nói tên nhãn đã là một sự trừu tượng hóa (từ độ lệch). Ngoài ra, bối cảnh đóng một vai trò: ví dụ: add eax,2có thể được dịch sang 83 c0 02hoặc sang 66 83 c0 02, tùy thuộc vào chỉ thị mới nhất xảy ra như thế nào use16.
Ruslan

15

Trình biên dịch thường chuyển đổi mã cấp cao trực tiếp sang ngôn ngữ máy, nhưng nó có thể được xây dựng theo cách mô đun để một back-end phát ra mã máy và mã lắp ráp khác (như GCC). Giai đoạn tạo mã tạo ra "mã" là một số biểu diễn bên trong của mã máy, sau đó phải được chuyển đổi sang định dạng có thể sử dụng như ngôn ngữ máy hoặc mã lắp ráp.


Ngoài ra, nếu nguồn có thể bao gồm một số mã lắp ráp, thì phải có sẵn một cơ chế để dịch cụm lắp ráp nội tuyến đó.
Paul A. Clayton

Tại sao ngôn ngữ lắp ráp lại hiệu quả đến vậy, mặc dù nó cũng được viết bằng tiếng Anh và cách bộ xử lý hiểu nó?
CODERSAM

1
Ngôn ngữ hội là một mô tả "tiếng Anh" của mã máy.
Yuval Filmus

11

Trong lịch sử, một số trình biên dịch đáng chú ý đã xuất mã máy trực tiếp. Tuy nhiên, có một số khó khăn khi làm như vậy. Nói chung, ai đó đang cố gắng xác nhận rằng trình biên dịch đang hoạt động chính xác sẽ dễ dàng kiểm tra đầu ra mã lắp ráp hơn mã máy. Hơn nữa, có thể (và là phổ biến trong lịch sử) để sử dụng trình biên dịch C hoặc Pascal một lần để tạo tệp ngôn ngữ lắp ráp, sau đó có thể được xử lý bằng trình biên dịch hai lần. Việc tạo mã trực tiếp sẽ yêu cầu sử dụng trình biên dịch C hoặc Pascal hai lượt hoặc sử dụng trình biên dịch một lượt theo sau là một số phương tiện của các địa chỉ nhảy về phía trước vá lại [nếu môi trường thời gian chạy làm cho kích thước của chương trình được khởi chạy có sẵn trong một điểm cố định, một trình biên dịch có thể viết một danh sách các bản vá ở cuối mã và có mã khởi động áp dụng các bản vá đó khi chạy; cách tiếp cận như vậy sẽ tăng kích thước thực thi lên khoảng bốn byte cho mỗi điểm vá, nhưng sẽ cải thiện tốc độ tạo chương trình].

Nếu mục tiêu là có một trình biên dịch chạy nhanh, việc tạo mã trực tiếp có thể hoạt động tốt. Tuy nhiên, đối với hầu hết các dự án, chi phí tạo mã ngôn ngữ lắp ráp và lắp ráp nó thực sự không phải là một vấn đề lớn hiện nay. Có các trình biên dịch tạo mã theo một hình thức có thể tương tác độc đáo với mã được tạo bởi các trình biên dịch khác nói chung là một lợi ích đủ lớn để chứng minh sự gia tăng thời gian biên dịch.


1

Ngay cả các nền tảng sử dụng cùng một tập lệnh có thể có các định dạng tệp đối tượng có thể định vị lại khác nhau. Tôi có thể nghĩ về "a.out" (UNIX sớm), OMF, MZ (MS-DOS EXE), NE (Windows 16 bit), COFF (UNIX System V), Mach-O (OS X và iOS) và ELF (Linux và các loại khác), cũng như các biến thể của chúng, chẳng hạn như XCOFF (AIX), ECOFF (SGI) và Portable Executable (PE) dựa trên COFF trên Windows 32 bit. Một trình biên dịch tạo ra ngôn ngữ lắp ráp không cần biết nhiều về các định dạng tệp đối tượng, cho phép trình biên dịch và trình liên kết đóng gói kiến ​​thức đó trong một quy trình riêng biệt.

Xem thêm Sự khác biệt giữa OMF và COFF trên Stack Overflow.


1

Thông thường trình biên dịch làm việc nội bộ với các chuỗi hướng dẫn. Mỗi lệnh sẽ được biểu diễn bằng cấu trúc dữ liệu thể hiện tên hoạt động, toán hạng và vv. Khi các toán hạng là địa chỉ, các địa chỉ đó thường sẽ là các tham chiếu tượng trưng, ​​không phải là các giá trị cụ thể.

Trình biên dịch đầu ra tương đối đơn giản. Đó là vấn đề khá lớn của việc lấy các trình biên dịch cấu trúc dữ liệu nội bộ và đưa nó vào một tệp văn bản theo một định dạng cụ thể. Trình biên dịch đầu ra cũng tương đối dễ đọc, rất hữu ích khi bạn cần kiểm tra trình biên dịch đang làm gì.

Xuất ra các tệp đối tượng nhị phân là công việc nhiều hơn đáng kể. Người viết trình biên dịch cần biết làm thế nào tất cả các hướng dẫn được mã hóa (có thể khác xa với một số CPUS), họ cần chuyển đổi một số tham chiếu tượng trưng sang các địa chỉ tương đối của chương trình và các hướng dẫn khác thành một dạng dữ liệu meta trong tệp đối tượng nhị phân . Họ cần phải viết tất cả mọi thứ trong một định dạng có tính hệ thống cao.

Có, bạn hoàn toàn có thể tạo một trình biên dịch có thể xuất trực tiếp các đối tượng nhị phân mà không cần viết ra trình biên dịch như một bước trung gian. Câu hỏi giống như rất nhiều điều trong phát triển phần mềm là liệu việc giảm thời gian biên dịch có xứng đáng với công việc phát triển và bảo trì bổ sung hay không.

Trình biên dịch mà tôi quen thuộc nhất (freepascal) có thể xuất trình biên dịch chương trình trên tất cả các nền tảng nhưng chỉ có thể xuất các đối tượng nhị phân trực tiếp trên một tập hợp con của các nền tảng.


1

Một trình biên dịch sẽ có thể tạo ra một đầu ra của trình biên dịch, ngoài mã có thể định vị lại thông thường là vì lợi ích của người lập trình.

Một lần tôi không tìm thấy lỗi trong chương trình C chạy trên Unix System V trên máy LSI-11. Dường như không có gì để làm việc Cuối cùng trong tuyệt vọng tôi đã có trình biên dịch C đáng tin cậy bài tiết một phiên bản dịch hợp ngữ của bản dịch. Cuối cùng tôi đã tìm thấy lỗi! Trình biên dịch đã phân bổ nhiều thanh ghi hơn so với tồn tại trong máy! (Trình biên dịch phân bổ các thanh ghi R0 đến R8 trên một máy chỉ có các thanh ghi R0 đến R7.) Tôi đã quản lý để khắc phục lỗi trong trình biên dịch và chương trình của tôi đã hoạt động.

Một lợi ích khác của việc có đầu ra của trình biên dịch chương trình là cố gắng sử dụng các thư viện "tiêu chuẩn" sử dụng một giao thức truyền tham số khác. Các trình biên dịch C sau này cho phép tôi thiết lập giao thức với một tham số ("pascal" sẽ khiến trình biên dịch thêm các tham số theo thứ tự được đưa ra trái ngược với tiêu chuẩn C đảo ngược thứ tự).

Tuy nhiên, một lợi ích khác là cho phép lập trình viên thấy công việc kinh khủng mà trình biên dịch của anh ta đang làm. Một câu lệnh C đơn giản mất khoảng 44 lệnh máy. Các giá trị được tải từ bộ nhớ và sau đó nhanh chóng bị loại bỏ. vân vân, vân vân, vân vân ...

Cá nhân tôi tin rằng có một trình biên dịch thay vì một mô-đun đối tượng có thể di dời là thực sự ngu ngốc. Trong khi biên dịch chương trình của bạn, trình biên dịch thu thập rất nhiều thông tin về chương trình của bạn. Nó thường lưu trữ tất cả thông tin này trong một cái gì đó gọi là Bảng biểu tượng. Sau khi bài tiết mã trình biên dịch mã, nó sẽ ném tất cả bảng thông tin này. Trình biên dịch sau đó kiểm tra mã bài tiết và thu thập lại một số thông tin mà trình biên dịch đã có. Tuy nhiên, trình biên dịch chương trình không biết gì về câu lệnh If của câu lệnh For hoặc câu lệnh While. Vì vậy, tất cả các thông tin này là thiếu. Sau đó, trình biên dịch tạo ra mô-đun đối tượng có thể định vị lại mà trình biên dịch không làm được.

Tại sao???

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.