Tại sao các tệp thực thi phụ thuộc vào HĐH mà không phụ thuộc vào CPU?


16

Nếu tôi viết chương trình C và biên dịch nó thành một .exetệp, .exetệp đó chứa các hướng dẫn máy thô cho CPU. (Tôi nghĩ).

Nếu vậy, làm thế nào tôi có thể chạy tệp được biên dịch trên bất kỳ máy tính nào chạy phiên bản Windows hiện đại? Mỗi họ CPU có một bộ hướng dẫn khác nhau. Vậy tại sao bất kỳ máy tính nào chạy HĐH phù hợp đều có thể hiểu các hướng dẫn trong .exetệp của tôi , bất kể đó là CPU vật lý?

Ngoài ra, thường trong các trang web trong trang "tải xuống" của một số ứng dụng, bạn có tải xuống cho Windows, cho Linux và cho Mac (thường là hai lần tải xuống cho mỗi HĐH, cho máy tính 86 và 64 bit). Tại sao không có nhiều lượt tải xuống nữa, cho mỗi họ CPU?


4
CPU có tiêu chuẩn như x86, 64b, v.v .. thực thi DO phụ thuộc vào CPU. Bạn không thể chạy exe mà bạn đã đề cập trên một số CPU đặc biệt như RISC, cũng có rất nhiều CPU có mục đích đặc biệt
InformedA

Các hệ điều hành được tạo thành từ các tệp thực thi và chúng phụ thuộc vào CPU chứ không phụ thuộc vào các HĐH vì chúng là HĐH.
Tulains Córdova

Vì khả năng tương thích ngược.
MiKL

2
thường là hai lần tải xuống cho mỗi HĐH, cho máy tính 86 và 64 bit : Tôi hiểu rằng đó là sự phụ thuộc của các tệp thực thi vào CPU.
mouviciel

Câu trả lời:


37

Các tệp thực thi phụ thuộc vào cả HĐH và CPU:

  • Tập lệnh: Các lệnh nhị phân trong tệp thực thi được CPU giải mã theo một số bộ lệnh. Hầu hết các CPU tiêu dùng đều hỗ trợ các bộ hướng dẫn x86 (thời gian 32bit trực tiếp) và / hoặc AMD64 (siêu tốc 64bit). Một chương trình có thể được biên dịch cho một trong hai tập lệnh này, nhưng không phải cả hai. Có phần mở rộng cho các bộ hướng dẫn này; hỗ trợ cho những thứ này có thể được truy vấn trong thời gian chạy. Các phần mở rộng như vậy cung cấp hỗ trợ SIMD, ví dụ. Tối ưu hóa trình biên dịch có thể cố gắng tận dụng các tiện ích mở rộng này nếu chúng có mặt, nhưng thường cũng cung cấp một đường dẫn mã hoạt động mà không có bất kỳ tiện ích mở rộng nào.

  • Định dạng nhị phân: Tệp thực thi phải tuân theo một định dạng nhị phân nhất định, cho phép hệ điều hành tải chính xác, khởi tạo và khởi động chương trình. Windows chủ yếu sử dụng định dạng Portable Executable, trong khi Linux sử dụng ELF.

  • API hệ thống: Chương trình có thể đang sử dụng các thư viện, phải có mặt trên hệ thống thực thi. Nếu một chương trình sử dụng các chức năng từ API Windows, nó không thể chạy trên Linux. Trong thế giới Unix, các API hệ điều hành trung tâm đã được chuẩn hóa thành POSIX: một chương trình chỉ sử dụng các chức năng POSIX sẽ có thể chạy trên bất kỳ hệ thống Unix phù hợp nào, như Mac OS X và Solaris.

Vì vậy, nếu hai hệ thống cung cấp cùng một API hệ thống và thư viện, hãy chạy trên cùng một tập lệnh và sử dụng cùng định dạng nhị phân, thì một chương trình được biên dịch cho một hệ thống cũng sẽ chạy trên hệ thống kia.

Tuy nhiên, có nhiều cách để đạt được nhiều khả năng tương thích hơn:

  • Các hệ thống chạy trên tập lệnh AMD64 thường sẽ chạy các tệp thực thi x86. Định dạng nhị phân cho biết chế độ nào sẽ chạy. Xử lý cả chương trình 32 bit và 64 bit đòi hỏi nỗ lực bổ sung của hệ điều hành.

  • Một số định dạng nhị phân cho phép một tệp chứa nhiều phiên bản của chương trình, được biên dịch cho các tập lệnh khác nhau. Các mã nhị phân béo như thế này đã được Apple khuyến khích khi họ chuyển từ kiến ​​trúc PowerPC sang x86.

  • Một số chương trình không được biên dịch thành mã máy, nhưng với một số đại diện trung gian. Điều này sau đó được dịch nhanh chóng theo hướng dẫn thực tế, hoặc có thể được giải thích. Điều này làm cho một chương trình độc lập với kiến ​​trúc cụ thể. Một chiến lược như vậy đã được sử dụng trên Hệ thống p UCSD.

  • Một hệ điều hành có thể hỗ trợ nhiều định dạng nhị phân. Windows tương thích ngược và vẫn hỗ trợ các định dạng từ thời DOS. Trên Linux, Wine cho phép các định dạng Windows được tải.

  • Các API của một hệ điều hành có thể được thực hiện lại cho một hệ điều hành máy chủ khác. Trên Windows, Cygwin và hệ thống con POSIX có thể được sử dụng để có được môi trường (hầu hết) tuân thủ POSIX. Trên Linux, Wine giới thiệu lại nhiều API của Windows.

  • Các thư viện đa nền tảng cho phép một chương trình độc lập với API hệ điều hành. Nhiều ngôn ngữ lập trình có các thư viện chuẩn cố gắng đạt được điều này, ví dụ Java và C.

  • Trình giả lập mô phỏng một hệ thống khác bằng cách phân tích định dạng nhị phân nước ngoài, diễn giải các hướng dẫn và cung cấp việc thực hiện lại tất cả các API cần thiết. Trình giả lập thường được sử dụng để chạy các trò chơi Nitendo cũ trên PC hiện đại.


10
Bạn nên đề cập rằng cả java và .net là những ví dụ về việc sử dụng định dạng trung gian - các định dạng trung gian rất phổ biến hiện nay và không chỉ là một di tích của hệ thống năm 1970 chạy hết 5 1/4 đĩa mềm.
jmoreno

@AKoscianski cảm ơn bạn đã chỉnh sửa . Tuy nhiên, tôi nghĩ rằng thiết kế bảo mật không phải là lý do tại sao các tệp thực thi phụ thuộc vào hệ điều hành, mà là lý do tại sao chúng ta có hệ điều hành so với phân chia vùng người dùng ở vị trí đầu tiên. Các API khác nhau cho chức năng hệ điều hành được bảo vệ như vậy đã được xử lý bởi phần API của Hệ thống API của câu trả lời này.
amon

2

99% máy tính hiện tại chạy Windows có bộ xử lý 64 bit, cũng có khả năng chạy phần mềm 32 bit. Một phần trăm khác có bộ xử lý 32 bit. Vì vậy, phần mềm được xây dựng cho bộ xử lý 32 bit chạy ở mọi nơi. Phần mềm được xây dựng cho bộ xử lý 64 bit chạy trên mọi PC mà người tạo ra phần mềm quan tâm.

MacOS X và iOS hỗ trợ "nhị phân chất béo" - những gì bạn tải xuống thực sự có thể chứa các phiên bản cho các bộ xử lý khác nhau. Không ai xây dựng các ứng dụng cho bộ xử lý PowerPC nữa, nhưng tại một số năm trước, một tệp thực thi có thể chứa PowerPC, Intel 32 bit và phiên bản Intel 64 bit, và phiên bản bên phải sẽ được thực thi. Trên iOS hiện nay, khi bạn tải xuống một ứng dụng, bạn sẽ có được một phiên bản phù hợp với bộ xử lý trên thiết bị của bạn. Tải xuống trên một thiết bị khác và bạn có được một phiên bản khác. Hoàn toàn vô hình cho người dùng.


-1

Một exe chứa nhiều thông tin hơn chỉ là mã máy thô. HĐH đọc được điều này khi tải nó và có thể tìm ra cách nó nên chạy.

Khi bạn biên dịch, bạn thường đặt CPU mục tiêu, nếu bạn không biên dịch sẽ chọn CPU hiện tại của bạn và sẽ tự giới hạn chỉ chọn các hướng dẫn chung cho CPU của bạn và các phiên bản cũ hơn của CPU. Nếu bạn muốn sử dụng một hướng dẫn mới lạ mắt dành riêng cho việc sửa đổi CPU mục tiêu nhất định của mình, bạn có thể nói với trình biên dịch hoặc mã hóa thủ công bằng mã nội bộ hoặc mã lắp ráp nội tuyến. Tuy nhiên, chương trình của bạn sẽ gặp sự cố nếu nó chạy trên CPU không hỗ trợ hướng dẫn đó.

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.