2016-02-24 20 views
6

Như tôi đã hiểu, mã C được biên dịch thành mã máy (lắp ráp) trên máy của ai đó và nó trở thành tệp exe có thể chạy trên nhiều bộ xử lý (máy) khác nhau. Nhưng kể từ khi bộ vi xử lý khác nhau có mã lắp ráp duy nhất của riêng mình như thế nào có thể mã này chạy? Không exe biên dịch chỉ có thể chạy trên một loại bộ vi xử lý?Mã C có thể chạy trên các bộ vi xử lý khác nhau như thế nào?

+5

Nhiều mô hình bộ vi xử lý khác nhau có thể là một phần của cùng một "gia đình" và chia sẻ cùng một ngôn ngữ máy. –

+7

Nó giống như cách mà cùng một loại xăng có thể được sử dụng trong nhiều, nhưng không phải tất cả, xe hơi, mặc dù mỗi chiếc xe đều có động cơ riêng. –

+0

Nhưng không thể tệp exe có thể chạy trên tất cả các máy cửa sổ, ngay cả khi chúng có bộ xử lý hoàn toàn khác nhau. – Melkor

Trả lời

14

Khi bạn biên dịch chương trình thành mã máy, bạn phải chọn bộ chỉ dẫn mã máy, có thể là chế độ để chạy máy (nếu có) và định dạng mã được lưu trữ.

Tất cả các lựa chọn đó giới hạn nền tảng đích mà mã có thể được thực thi.

  • Các hướng dẫn thiết lập rộng rãi phụ thuộc vào loại CPU: x86 ("IBM tương thích"), PowerPC, ARM, MIPS, DEC Alpha, Motorola 68k, ... Trong mỗi gia đình CPU, có rất nhiều các tính năng phụ và các thế hệ để lựa chọn (ví dụ cho x86, có i386, SSE, AVX, ...). CPU mới hơn có thể thực thi mã giới hạn cho các thế hệ cũ hơn, do đó có thể có một tập con chung.

  • Chế độ bộ xử lý trên x86 tùy thuộc vào môi trường: chế độ thực cho các chương trình MS-DOS và bất cứ thứ gì bạn chạy khi khởi động, chế độ được bảo vệ, các chế độ địa chỉ khác nhau có thể có sẵn trong một số trường hợp (chế độ không thực) ...

  • Định dạng nhị phân cần phải được hệ điều hành nhận dạng, hoặc thường là bằng cơ chế tải bao giờ bạn có: PE cho Windows, ELF cho Linux hiện đại, a.out trong những ngày cũ, ... hệ thống có thể cung cấp bộ nạp cho nhiều định dạng nhị phân.

Đây là cấp cơ bản nhất của thông số nền tảng bạn chọn khi biên dịch và chương trình của bạn sẽ chỉ chạy trên nền tảng đồng ý về lựa chọn này. Tuy nhiên, có nhiều hạn chế thực tế hơn đối với các chương trình trong thế giới thực, chẳng hạn như giao diện hệ điều hành và tính khả dụng của các thư viện khung, cũng cần phải khớp. Ví dụ, trong khi nó không khó để đọc và chạy Windows PE nhị phân trong Linux, mã chứa trong đó không có ý nghĩa trên Linux bởi vì nó sử dụng Windows phần mềm cụ thể ngắt. Tuy nhiên, bằng cách chặn và dịch những người đó, hoàn toàn có thể chạy những tệp nhị phân đó trên Linux sau tất cả.

+2

Ngoài ra, (cụ thể) định dạng tệp PE chứa một trường rõ ràng ** nêu rõ ** CPU là gì cho: "' Máy' CPU mà tệp này dành cho. Các ID CPU sau được xác định: .. . "(https://msdn.microsoft.com/en-us/library/ms809762.aspx). – usr2564301

+0

_ "giao diện hệ điều hành và tính sẵn có của thư viện khung, cũng cần phải khớp" _ Tôi nghĩ đó là điều quan trọng cần xem xét ở đây (cho OP): Mặc dù hầu hết các máy tính đều sử dụng CPU x86 và (rộng rãi) nói cùng một ngôn ngữ, nó thường là hệ điều hành là yếu tố quyết định trong tính di động của các chương trình được biên dịch. Cửa sổ exe không thể chạy trên OSX, hoặc linux mà không có loại giả lập hoặc phiên dịch/thời gian chạy ở giữa (giống như Java được biên dịch để chạy trên JVM, không trực tiếp trên phần cứng) –

+0

@EliasVanOotegem: Có. Ví dụ, Wine chặn các cuộc gọi hệ thống Windows và cung cấp và triển khai thích hợp trên Linux, và gửi các thư viện Windows lõi (được cài đặt cho Linux), để bạn có thể chạy nhiều chương trình Windows trên Linux. (Tôi tưởng tượng nó có thể làm tương tự trên MacOS và BSD?) –

Các vấn đề liên quan