12/08/2018, 16:19

Assembly and how compilers work with it

Bài viết này chúng ta cùng tìm hiểu assembly là gì và trình biên dịch tạo ra nó như thế nào. Từ đó làm tiền đề để hiểu cách thức WebAssembly hoạt động. Trong bài viết về JIT, chúng ta đã nói về cách giao tiếp với máy giống như giao tiếp với người ngoài hành tinh. Chúng ta hãy nhìn vào cách não ...

Bài viết này chúng ta cùng tìm hiểu assembly là gì và trình biên dịch tạo ra nó như thế nào. Từ đó làm tiền đề để hiểu cách thức WebAssembly hoạt động.

Trong bài viết về JIT, chúng ta đã nói về cách giao tiếp với máy giống như giao tiếp với người ngoài hành tinh. Chúng ta hãy nhìn vào cách não bộ người ngoài hành tinh hoạt động như thế nào (bộ não của máy tính phân tích và hiểu được thông tin liên lạc đến với nó như thế nào).

Có một phần của bộ não này là dành riêng cho những suy nghĩ-những thứ như phép cộng trừ nhân chia, hoặc xử lý logic. Cũng có một bộ phận của bộ não gần đó cung cấp bộ nhớ ngắn hạn và một phần khác cung cấp bộ nhớ dài hạn. Những phần khác nhau có tên:

  • Phần suy nghĩ là Arithmetic-logic Unit (ALU).
  • Bộ nhớ ngắn hạn được cung cấp bởi thanh ghi (registers).
  • Bộ nhớ dài hạn là bộ nhớ truy cập ngẫu nhiên (RAM).

Các câu lệnh trong mã máy được gọi là các hướng dẫn (instructions). Điều gì xảy ra khi một trong những instruction này đi vào trong não? Nó được chia thành nhiều phần khác nhau có ý nghĩa khác nhau.

Ví dụ, một bộ não có dây như thế này luôn luôn lấy 6 bit đầu tiên và dẫn vào ALU. Dựa vào vị trí của những số 1 và 0 thì ALU sẽ biết được rằng nó cần phải cộng 2 phần tử với nhau. Đoạn mã 6 bit này được gọi là "opcode", hoặc mã hoạt động, bởi vì nó nói với ALU những hoạt động cần thực hiện là gì.

Sau đó, bộ não này sẽ lấy hai khối tiếp theo, mỗi khối 3 bit để xác định hai con số mà nó cần thực hiện phép cộng. Đây thực chất là địa chỉ của các thanh ghi.

Lưu ý chú thích bên trên mã máy ở đây, làm cho con người dễ hiểu điều gì đang xảy ra. Đây là assembly. Nó được gọi là symbolic machine code. Đó là cách để con người hiểu được mã máy.

Bạn có thể thấy ở đây có một mối quan hệ khá trực tiếp giữa assembly và mã máy cho máy này. Vì lý do này, có nhiều loại assembly khác nhau cho các loại kiến ​​trúc máy khác nhau mà bạn có thể có. Khi bạn có một kiến ​​trúc khác bên trong của một máy tính, nó có thể yêu cầu một ngôn ngữ assembly riêng. Ví dụ assembly của máy tính kiến trúc x86 sẽ khác với assembly của máy tính có kiến trúc ARM. Vì vậy, không chỉ có một mục tiêu cho bản dịch. Và chúng ta có nhiều loại mã máy khác nhau. Cũng như chúng ta nói những ngôn ngữ khác nhau, thì máy móc cũng vậy.

Với bản dịch từ con người sang người ngoài hành tinh, bạn có thể đi từ tiếng Anh, hoặc Nga, hoặc Mandarin sang Ngôn Ngữ Người ngoài hành tinh A hoặc B. Trong thuật ngữ lập trình, điều này giống như dịch từ ngôn ngữ C, hoặc C + +, hoặc Rust sang x86 hoặc ARM.

Bạn muốn có thể dịch bất kỳ một trong những ngôn ngữ lập trình cấp cao xuống bất kỳ một trong những ngôn ngữ assembly này (tương ứng với các kiến ​​trúc khác nhau). Một cách để làm điều này là tạo ra một tập hợp toàn bộ các trình thông dịch khác nhau có thể đi từ mỗi ngôn ngữ đến mỗi ngôn ngữ assembly. Như ví dụ dưới đây chúng ta cần 2 * 3 = 6 trình trông dịch khác nhau.

Điều đó sẽ không hiệu quả lắm. Để giải quyết vấn đề này, phần lớn trình biên dịch đặt ít nhất một lớp vào giữa. Trình biên dịch sẽ sử dụng ngôn ngữ lập trình cao cấp này và dịch nó sang một thứ gì đó không phải là mức cao, nhưng cũng không hoạt động ở mức mã máy. Và đó được gọi là một đại diện trung gian (IR). Sơ đồ cho thấy một sự trình bày trung gian giữa các ngôn ngữ cấp cao và các ngôn ngữ assembly, với các mũi tên đi từ các ngôn ngữ lập trình bậc cao đến đại diện trung gian, và sau đó từ đại diện trung gian đến ngôn ngữ assembly

Điều này có nghĩa là trình biên dịch có thể lấy bất kỳ một trong những ngôn ngữ cấp cao hơn làm input và dịch nó sang một ngôn ngữ IR. Từ đó, một phần khác của trình biên dịch có thể lấy IR đó làm input và biên dịch nó xuống một cái gì đó cụ thể cho kiến trúc mục tiêu. Phần front-end của trình biên dịch chuyển đổi từ ngôn ngữ lập trình cấp cao sang IR. Phần backend của trình biên dịch sẽ chuyển đổi từ IR tới mã assembly của kiến ​​trúc đích.

Kết luận

Đó là assembly và làm thế nào trình biên dịch có thể dịch ngôn ngữ lập trình cấp cao sang assembly. Trong bài tiếp theo, chúng ta sẽ thấy cách WebAssembly tuân theo điều này.

0