Mã hội vs mã máy vs mã đối tượng?


227

Sự khác biệt giữa mã đối tượng, mã máy và mã lắp ráp là gì?

Bạn có thể đưa ra một ví dụ trực quan về sự khác biệt của họ?


Tôi cũng tò mò về việc tên "mã đối tượng" đến từ đâu? Từ "đối tượng" có nghĩa là gì trong đó? Có phải nó bằng cách nào đó liên quan đến lập trình hướng đối tượng hay chỉ là sự trùng hợp của tên?
SasQ


Tôi không hỏi về mã đối tượng là gì, Captain Rõ ràng. Tôi đang hỏi về cái tên đó đến từ đâu và tại sao lại gọi là mã "object".
BarbaraKwarc

Câu trả lời:


296

Mã máy nhị phân (1 và 0) có thể được CPU thực thi trực tiếp. Nếu bạn mở tệp mã máy trong trình soạn thảo văn bản, bạn sẽ thấy rác, bao gồm các ký tự không thể in được (không, không phải các ký tự ký tự in được;)).

Mã đối tượng là một phần của mã máy chưa được liên kết thành một chương trình hoàn chỉnh. Đó là mã máy cho một thư viện hoặc mô-đun cụ thể sẽ tạo nên sản phẩm hoàn chỉnh. Nó cũng có thể chứa các phần giữ chỗ hoặc offset không tìm thấy trong mã máy của một chương trình đã hoàn thành. Trình liên kết sẽ sử dụng các trình giữ chỗ và offset này để kết nối mọi thứ lại với nhau.

Mã hội là văn bản thuần túy và (phần nào) mã nguồn có thể đọc được của con người mà hầu hết có tương tự 1: 1 trực tiếp với các hướng dẫn máy. Điều này được thực hiện bằng cách sử dụng tính năng ghi nhớ cho các hướng dẫn thực tế, các thanh ghi hoặc các tài nguyên khác. Các ví dụ bao gồm JMPMULTcho các hướng dẫn nhảy và nhân của CPU. Không giống như mã máy, CPU không hiểu mã lắp ráp. Bạn chuyển đổi lắp ráp mã để máy với việc sử dụng một lắp ráp hoặc một trình biên dịch , mặc dù chúng ta thường nghĩ đến các trình biên dịch gắn với ngôn ngữ lập trình cấp cao được trừu tượng hơn nữa từ các hướng dẫn CPU.

Xây dựng một chương trình hoàn chỉnh liên quan đến việc viết mã nguồn cho chương trình bằng ngôn ngữ lắp ráp hoặc ngôn ngữ cấp cao hơn như C ++. Mã nguồn được lắp ráp (đối với mã lắp ráp) hoặc được biên dịch (đối với các ngôn ngữ cấp cao hơn) thành mã đối tượng và các mô-đun riêng lẻ được liên kết với nhau để trở thành mã máy cho chương trình cuối cùng. Trong trường hợp các chương trình rất đơn giản, bước liên kết có thể không cần thiết. Trong các trường hợp khác, chẳng hạn như với IDE (môi trường phát triển tích hợp), trình liên kết và trình biên dịch có thể được gọi cùng nhau. Trong các trường hợp khác, một tập lệnh tạo hoặc giải pháp phức tạp có thể được sử dụng để cho môi trường biết cách xây dựng ứng dụng cuối cùng.

Cũng có những ngôn ngữ được giải thích hành xử khác nhau. Các ngôn ngữ được giải thích dựa vào mã máy của chương trình thông dịch viên đặc biệt. Ở cấp độ cơ bản, một trình thông dịch phân tích mã nguồn và ngay lập tức chuyển đổi các lệnh thành mã máy mới và thực thi chúng. Các trình thông dịch hiện đại, đôi khi còn được gọi là môi trường thời gian chạy hoặc máy ảo , phức tạp hơn nhiều: đánh giá toàn bộ các phần của mã nguồn tại một thời điểm, lưu trữ và tối ưu hóa khi có thể và xử lý các tác vụ quản lý bộ nhớ phức tạp. Một ngôn ngữ được dịch cũng có thể được biên dịch trước thành ngôn ngữ trung gian cấp thấp hơn hoặc mã byte, tương tự như mã lắp ráp.


24
+1: câu trả lời hay, nhưng có phần đơn giản - không phải tất cả các hướng dẫn lắp ráp được dịch 1: 1 thành hướng dẫn máy và các tệp đối tượng cũng có thể chứa dữ liệu khác (thông tin di dời, bảng biểu tượng, ...)
Christoph

5
Đã thêm một từ chồn cho vấn đề đầu tiên của bạn, được chỉnh sửa để làm cho thứ 2 rõ ràng hơn.
Joel Coehoorn

2
@Christoph: bạn nói "không phải tất cả các hướng dẫn lắp ráp đều được dịch 1: 1 thành hướng dẫn máy", vui lòng cho một ví dụ.
Olof Forshell

5
@Olof: Kiến trúc RISC đôi khi cung cấp một bộ hướng dẫn ảo cấp độ lắp ráp - ví dụ: hướng dẫn giả MIPS ( en.wikipedia.org/wiki/MIPS_arch architecture # Pudoudo_in cản )
Christoph

3
@Panzercrisis Không có gì được thêm bởi trình biên dịch. Đây là bản dịch trực tiếp những gì bạn đã viết cho các hướng dẫn máy thực tế. Và tôi sẽ không gọi mã bổ sung được đưa vào bởi trình biên dịch là "không cần thiết"
Joel Coehoorn

125

Các câu trả lời khác đã cho một mô tả tốt về sự khác biệt, nhưng bạn cũng yêu cầu một hình ảnh. Dưới đây là một sơ đồ cho thấy họ đi từ mã C đến một tệp thực thi.


3
Tôi thấy điều này thực sự hữu ích, nhưng nó thiếu nhãn "Mã máy"
Alexx Roche

Vì vậy, khi nó ở cấp mã thực thi, điều đó có tương đương với mã máy không?
CMCDragonkai

3
Trong ngữ cảnh của sơ đồ này, "mã đối tượng" là mã máy.
Đồ họa Noob

5
Trên thực tế, cả mã đối tượng và mã thực thi đều là mã máy. sự khác biệt là mã đối tượng không phải là chương trình hoàn thành. Nó cần được kết hợp với các mã thư viện / mô-đun trợ giúp khác như được chỉ ra trong sơ đồ để tạo thành một chương trình / mã thực thi hoàn chỉnh.
okey_on

@okeyxyz ở mức độ nào sẽ đúng khi nói nó được bộ xử lý trực tiếp thực hiện? Sau trình biên dịch, sau trình liên kết, sau trình nạp, sau khi nó được chuyển đổi thành vi điều khiển?
Celeritas

49

Mã hội là một đại diện dễ đọc của con người về mã máy:

mov eax, 77
jmp anywhere

Mã máy là mã thập lục phân thuần túy:

5F 3A E3 F1

Tôi giả sử bạn có nghĩa là mã đối tượng như trong một tệp đối tượng. Đây là một biến thể của mã máy, với một điểm khác biệt là các bước nhảy được sắp xếp theo tham số sao cho một trình liên kết có thể điền chúng vào.

Trình biên dịch được sử dụng để chuyển đổi mã lắp ráp thành mã máy (mã đối tượng) Trình liên kết liên kết một số tệp đối tượng (và thư viện) để tạo tệp thực thi.

Tôi đã từng viết một chương trình biên dịch chương trình biên dịch thuần túy (không có trình biên dịch sẵn), may mắn thay, điều này đã quay trở lại với 6502 cũ (tốt). Nhưng tôi rất vui vì có các trình biên dịch cho các opium pentium.


76
Không không không không. Mã máy không phải là mã hex. đó là nhị phân thuần túy. Mã hex chỉ là một đại diện thuận tiện của nhị phân.
Breton

56
Nếu chúng ta thực sự đi vào cực đoan, nó không phải là nhị phân, thì đó là một lượng điện được lưu trữ trong một mạch điện. ;-)
Toon Krijthe

17
Phải, tất nhiên. Có một mối quan hệ giữa thập lục phân và cái mà bạn sẽ gọi là "Mã máy", nhưng không hoàn toàn chính xác khi nói thập lục phân mã máy. Đó là tất cả những gì tôi đang cố nói.
Breton

9
@Breton Theo nghĩa đó, không có thứ gọi là "mã hex" phải không? "Mã hex" chỉ là một cách xem mã máy. Bạn có thể xem mã máy theo hệ thập lục phân, nhị phân, bát phân, thập phân hoặc theo cách bạn muốn. Cũng một lần nữa theo nghĩa đó, không có "mã nhị phân" là tốt. Một lần nữa, "mã nhị phân" chỉ là một cách xem mã máy.
Utku

9
@Breton Những gì bạn nói không thực sự có ý nghĩa nhiều .. Nhị phân là một cách biểu diễn, giống như hex. Nếu nó không phải là hex, nó cũng không phải là nhị phân.
Koray Tugay

18

8B 5D 32 là mã máy

mov ebx, [ebp+32h] là lắp ráp

lmylib.sochứa 8B 5D 32là mã đối tượng


8

Một điểm chưa được đề cập là có một vài loại mã lắp ráp khác nhau. Ở dạng cơ bản nhất, tất cả các số được sử dụng trong hướng dẫn phải được chỉ định là hằng số. Ví dụ:

$ 1902: BD 37 14: LDA $ 1437, X
$ 1905: 85 03: STA $ 03
$ 1907: 85 09: STA $ 09
$ 1909: CA: DEX
$ 190A: 10: BPL $ 1902

Đoạn mã trên, nếu được lưu trữ tại địa chỉ $ 1900 trong hộp mực Atari 2600, sẽ hiển thị một số dòng có màu khác nhau được lấy từ một bảng bắt đầu tại địa chỉ $ 1437. Trên một số công cụ, nhập địa chỉ, cùng với phần ngoài cùng bên phải của dòng trên, sẽ lưu vào bộ nhớ các giá trị được hiển thị trong cột giữa và bắt đầu dòng tiếp theo với địa chỉ sau. Nhập mã ở dạng đó thuận tiện hơn nhiều so với gõ hex, nhưng người ta phải biết địa chỉ chính xác của mọi thứ.

Hầu hết các nhà lắp ráp cho phép một người sử dụng địa chỉ tượng trưng. Đoạn mã trên sẽ được viết giống như:

cầu vồng_lp:
  lda ColorTbl, x
  sta WSYNC
  sta
  dex
  cầu vồng bpl

Trình biên dịch sẽ tự động điều chỉnh hướng dẫn LDA để nó tham chiếu đến bất kỳ địa chỉ nào được ánh xạ tới nhãn ColorTbl. Sử dụng kiểu trình biên dịch mã này giúp cho việc viết và chỉnh sửa mã dễ dàng hơn nhiều so với khả năng nếu người ta phải bấm tay và duy trì tất cả các địa chỉ.


1
+1. Một điểm bổ sung thêm: cũng có những ngôn ngữ khác nhau lắp ráp cú pháp , hầu hết con người nổi tiếng Intel và AT & T .
informatik01

1
@ notifyatik01: Làm thế nào về Intel 8080 mnemonics vs Zilog Z80? Tôi đoán rằng trước cuộc chiến cú pháp Intel vs AT & T.
supercat

Không tranh luận, tôi chỉ đề cập đến khía cạnh đó (cú pháp khác nhau) và đưa ra một ví dụ về hai cú pháp phổ biến nhất / nổi tiếng / nổi tiếng.
informatik01

4

Mã nguồn, mã hội, mã máy, mã đối tượng, mã byte, tệp thực thi và tệp thư viện.

Tất cả những điều khoản này thường rất khó hiểu đối với hầu hết mọi người vì thực tế rằng họ nghĩ rằng chúng là loại trừ lẫn nhau . Xem sơ đồ để hiểu mối quan hệ của họ. Mô tả của mỗi thuật ngữ được đưa ra dưới đây.


Các loại mã


Mã nguồn

Hướng dẫn bằng ngôn ngữ có thể đọc được (lập trình) của con người


Mã cấp cao

Các hướng dẫn được viết bằng ngôn ngữ cấp cao (lập trình)
, ví dụ: chương trình C, C ++ và Java


Mã hội

Hướng dẫn viết bằng ngôn ngữ lắp ráp (loại ngôn ngữ lập trình cấp thấp). Là bước đầu tiên của quá trình biên dịch, mã cấp cao được chuyển đổi thành dạng này. Đó là mã lắp ráp sau đó được chuyển đổi thành mã máy thực tế. Trên hầu hết các hệ thống, hai bước này được thực hiện tự động như một phần của quy trình biên dịch.
ví dụ: chương trình


Mã đối tượng

Sản phẩm của một quá trình biên dịch. Nó có thể ở dạng mã máy hoặc mã byte.
ví dụ: file.o


Mã máy

Hướng dẫn bằng ngôn ngữ máy.
ví dụ: a.out


Mã byte

Hướng dẫn trong một hình thức trung gian có thể được thực hiện bởi một trình thông dịch như JVM.
ví dụ: tệp lớp Java


Tập tin thực thi

Các sản phẩm của liên kết truy cập. Chúng là mã máy có thể được CPU thực thi trực tiếp.
ví dụ: tệp .exe.

Lưu ý rằng trong một số ngữ cảnh, một tệp chứa mã byte hoặc hướng dẫn ngôn ngữ kịch bản cũng có thể được coi là có thể thực thi được.


Thư viện tập tin

Một số mã được biên dịch thành biểu mẫu này vì các lý do khác nhau như khả năng sử dụng lại và sau đó được sử dụng bởi các tệp thực thi.


1
Tôi sẽ lập luận rằng không phải tất cả các hội đồng thực sự là nguồn theo nghĩa nghiêm ngặt nhất của mã được viết và / hoặc duy trì bởi con người. Thông thường, nó được tạo ra từ nguồn và không bao giờ dành cho tiêu dùng của con người (ví dụ: gcc thực sự tạo ra văn bản asm mà nó cung cấp cho trình biên dịch mã riêng biệt, thay vì có trình biên dịch tích hợp bên trong cc1tệp thực thi). Tôi nghĩ rằng vòng tròn asm nên nhô ra phía bên trái của vòng tròn "nguồn", bởi vì một số asm chỉ là asm, không phải là nguồn. Tất nhiên, nó không bao giờ là mã đối tượng , nhưng một số asm là một bước trên con đường từ nguồn đến tệp đối tượng.
Peter Cordes

@PeterCordes Cảm ơn bạn rất nhiều vì đã bình luận. Tôi đã không biết những gì bạn nói về hoạt động của gcc. Tuy nhiên, tôi sợ nếu tôi có thể hoàn toàn đồng ý với bạn. Ý tôi là, mã nguồn là thứ được viết bằng ngôn ngữ lập trình dễ đọc của con người. Nó có thể hoặc không thể được viết hoặc duy trì bởi con người. Tôi chắc chắn rằng bạn sẽ nhận thức được các bộ chuyển đổi. Từ quan điểm của bạn, bạn sẽ đặt sản phẩm của trình biên dịch như vậy? Mã nguồn hay cái gì khác? Vui long sửa cho tôi nêu tôi sai. Bình luận thêm luôn được chào đón.
Bertram Gilfoyle

1

Mã hội được thảo luận ở đây .

"Ngôn ngữ lắp ráp là ngôn ngữ cấp thấp cho các máy tính lập trình. Nó thực hiện một biểu tượng tượng trưng cho mã máy số và các hằng số khác cần thiết để lập trình một kiến ​​trúc CPU cụ thể."

Mã máy được thảo luận ở đây .

"Mã máy hoặc ngôn ngữ máy là một hệ thống các hướng dẫn và dữ liệu được thực thi trực tiếp bởi đơn vị xử lý trung tâm của máy tính."

Về cơ bản, mã trình biên dịch là ngôn ngữ và nó được dịch sang mã đối tượng (mã gốc mà CPU chạy) bởi một trình biên dịch (tương tự như trình biên dịch).


1

Tôi nghĩ rằng đây là những khác biệt chính

  • khả năng đọc mã
  • kiểm soát mã của bạn đang làm gì

Khả năng đọc có thể làm cho mã được cải thiện hoặc thay thế 6 tháng sau khi được tạo bằng nỗ lực litte, mặt khác, nếu hiệu suất là quan trọng, bạn có thể muốn sử dụng ngôn ngữ cấp thấp để nhắm mục tiêu phần cứng cụ thể mà bạn sẽ có trong sản xuất, vì vậy để có được thực hiện nhanh hơn.

IMO ngày nay máy tính đủ nhanh để cho phép lập trình viên thực hiện nhanh với OOP.


1

Hội là thuật ngữ mô tả ngắn mà con người có thể hiểu có thể được dịch trực tiếp sang mã máy mà CPU thực sự sử dụng.

Mặc dù có thể hiểu được phần nào bởi con người, nhưng Trình biên dịch vẫn ở mức độ thấp. Phải mất rất nhiều mã để làm bất cứ điều gì hữu ích.

Vì vậy, thay vào đó chúng tôi sử dụng các ngôn ngữ cấp cao hơn như C, BASIC, FORTAN (OK tôi biết tôi đã hẹn hò với chính mình). Khi biên dịch chúng tạo mã đối tượng. Ngôn ngữ ban đầu có ngôn ngữ máy là mã đối tượng của họ.

Nhiều ngôn ngữ ngày nay như JAVA và C # thường biên dịch thành mã byte không phải là mã máy, nhưng ngôn ngữ dễ dàng được giải thích trong thời gian chạy để tạo mã máy.


Nhận xét của bạn về Java và C # - cả hai đều sử dụng trình biên dịch Just In Time để mã byte không bị diễn giải. C # (.NET nói chung) biên dịch sang Ngôn ngữ trung gian (IL) sau đó được JITed thành ngôn ngữ máy gốc cho CPU mục tiêu.
Craig Shearer

-1

Các tệp nguồn của các chương trình của bạn được biên dịch thành các tệp đối tượng và sau đó trình liên kết liên kết các tệp đối tượng đó lại với nhau, tạo ra một tệp thực thi bao gồm mã máy của kiến ​​trúc của bạn.

Cả tệp đối tượng và tệp thực thi đều liên quan đến mã máy của kiến ​​trúc ở dạng ký tự có thể in và không in được khi nó được mở bởi trình soạn thảo văn bản.

Tuy nhiên, sự phân đôi giữa các tệp là (các) tệp đối tượng có thể chứa các tham chiếu bên ngoài chưa được giải quyết (ví dụ như printf, chẳng hạn). Vì vậy, nó có thể cần phải được liên kết với các tệp đối tượng khác .. Có nghĩa là, các tham chiếu bên ngoài chưa được giải quyết là cần thiết để được giải quyết để có được tệp thực thi có thể chạy được bằng cách liên kết với các tệp đối tượng khác như thư viện thời gian chạy C / C ++ .

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.