Quá trình chuyển sang ngôn ngữ máy

Một phần của tài liệu Bài giảng: Cấu trúc máy tính và ghép nối pot (Trang 76 - 82)

c, Liên kết thông qua stack

5.2. Quá trình chuyển sang ngôn ngữ máy

Quá trình chuyển từ ngôn ngữ hợp ngữ sang ngôn ngữ máy được gọi là quá trình assembly. Quá trình này được thực hiện rất đơn giản vì nó được thực hiện như việc tra bảng từng lệnh. Công việc này rất đơn giản nhưng rất dễ nhầm lẫn nếu thực hiện bằng tay. Thông thường, quá trình này được thực hiện bởi một phần mềm được gọi là assembler

Một phần mềm assemble ít nhất phải có những khả năng sau

• Cho phép lập trình viên xác định chính xác nơi lưu trữ dữ liệu và chương trình tại thời điểm chạy chương trình

• Cung cấp phương tiện để lập trình viên khởi tạo giá trị dữ liệu trước khi chạy chương trình

• Cung cấp các phương án chuyển từ ngôn ngữ hợp ngữ sang ngôn ngữ

máy cho tất cả các lệnh hợp ngữ và ở tất cả các chế độđịa chỉ

• Cho phép sử dụng các nhãn biểu tượng để biểu diễn địa chỉ và hằng số • Cung cấp khả năng cho người lập trình xác định địa chỉ bắt đầu của

chương trình

• Có cơ chế cho phép sử dụng các biến được định nghĩa trong 1 chương trình này được sử dụng trong một chương trình độc lập khác

• Cung cấp khả năng thực hiện chương trình con

Để tìm hiểu thêm về vấn đề này, chúng ta sẽ thử chuyển mã chương trình bằng tay một chương trình đơn giản đã được nêu ở trong chương trước, đó là chương trình tính tổng 2 số nguyên

Hình 5.2. Cấu trúc lệnh trong ARC

Hình 5.2 cung cấp cho người đọc phương pháp mã hóa lệnh của máy tính ARC.

Đây chính là những đặc tính của các trường nhị phân trong ngôn ngữ máy giúp người đọc chuyển hợp ngữ sang ngôn ngữ máy.

Quá trình chuyn ng kép

Hầu hết chương trình biên dịch đều thực hiện chuyển ngữ 2 lần, hay còn có tên là “two-pass assemblers”. Bước đầu tiên là xác định địa chỉ, dữ liệu và loại mã lệnh, đồng thời chọn những mã lệnh sẽ chuyển sang ngôn ngữ máy (nhưng không tạo mã máy)

Địa chỉ của dữ liệu và mã máy được chỉ ra bởi một bộ đếm được biết đến bởi tên gọi location counter. Bộđếm này sẽ lưu lại địa chỉ của câu lệnh đang được xử lý hoặc dữ liệu đang được nạp vào vi xử lý. Bộđếm này bằng 0 khi khởi tạo lúc chương trình bắt đầu chạy và tăng dần theo mỗi lệnh được thực thi. Lệnh giả

.org có thể xác định được một giá trị của bộđếm này bằng giá trị đi kèm với nó. Ví dụ như câu lệnh sau

Câu lệnh này sẽ xác định bộđếm có giá trị là 1000 và lệnh kế tiếp nó sẽ có địa chỉ trong máy là các giá trị tiếp theo số 1000. Bộđếm này sẽ tạo thành một bảng các con số tăng dần. Trong suốt bước 1 này, chương trình hợp ngữ cũng sẽ kiểm tra hoạt động của các lệnh, chèn thêm các định nghĩa các biến hay hằng số vào bảng sốđó, quá trình này có tên là symbol table

Nguyên nhân đòi hỏi phải thực hiện chuyển mã 2 lần là ta sẽ phải thực hiện việc “đưa” những biến số, hằng số mà ta đã thực hiện symbol table vào chương trình mà ta cần chuyển mã

Bây giờ ta sẽ thực hiện việc chuyển mã lệnh đầu tiên trong hình 5.1. Ld [x], %r1

Khi bộ đếm đếm tới lệnh đầu tiên (thương được biết tới là quá trình nạp câu lệnh). Câu lệnh này có ý nghĩa là nạp nội dung của ô nhớ có tên là x, tức là ô nhớ %r0 + x từ bộ nhớ vào thanh ghi %r1. Lệnh này tương ứng với cấu trúc Memory format trong hình 5.2. Nghiên cứu loại mã lệnh này ta thấy trường đầu tiên trong mã lệnh là op có giá trị là 11. Mã thanh ghi đích trong cấu trúc lệnh này được chứa trong trường rd, trong ví dụ trên sẽ là 00001 vì đây là thanh ghi %r1. Trường op3 có giá trị là 000000 đối với lệnh ld (đối chiếu với hình 5.2.). Trường rs1 trong trường hợp này tương ứng với thanh ghi %r0. Giá trị x sẽ được cung cấp thông qua trường simm13. Bit i sẽ là bit tiếp theo. Bít này

được sử dụng để phân biệt giữa các định dạng nhớ khác nhau. Trong trường hợp này i=1. Trường simm13 tương ứng với địa chỉ x, vậy x phải la bao nhiêu ? Nhãn x xuất hiện sau 5 word sau lệnh đầu tiên có địa chỉ 2048. Mỗi word là 4 byte, do đó x sẽ có địa chỉ là 2048 + 5 * 4 = 2068. Biểu diễn bằng số nhị phân sẽ là 0100000010100

Như vậy, mã lệnh của lệnh đầu tiên sẽ là

Tương tự, lệnh tiếp theo là

Nhìn chung, quá trình chuyển mã sẽ được thực hiện tuần tự từ đầu tới cuối, mã lệnh sẽ được tạo ra lần lượt theo từng câu lệnh. Sự khó khăn sẽ chỉ xuất hiện nếu trong chương trình xuất hiện các lệnh gọi chương trình con với từ khóa call.

Hình 5.3. Chương trình khung của lệnh call

Khi chương trình chuyển mã lệnh call, nó hoàn toàn chưa biết được sub_r là gì cho đến khi sub_r được tìm thấy. Do đó, chương trình sẽ đưa sub_r vào bảng symbol table và đánh dấu là chưa được giải quyết. Khi tìm thấy sub_r, chương trình sẽ thực hiện quá trình khắc phục.

Hot động ca symbol table

Trong bước đầu của quá trình chuyển mã 2 bước, symbol table đã được tạo ra. Một nhãn hay một cái tên bất kỳ sẽ tương ứng với một giá trị được sử dụng trong suốt quá trình chuyển mã. Chúng ta sẽ tìm hiểu lại ví dụ trong hình 4.14

để làm rõ hơn hoạt động của symbol table

Bắt đầu từ lệnh giả .begin và bộ đếm sẽ có giá trị 2048 với lệnh giả .org 2048. Lệnh đầu tiên được tính đến là a_start .equ 3000. Với lệnh này, một biểu tượng a_start sẽ được thiết lập và nạp giá trị là 3000. Lưu ý

rằng lệnh này không tạo ra bất kỳ mã lệnh nào nên sẽ không chiếm địa chỉ trong bộ nhớ

Hình 5.4. Ví dụ hình 4.14

Quá trình chuyển mã sẽ bắt đầu với lệnh đầu tiên Ld [length], %r1

Lệnh này sẽ được chuyển mã tại địa chỉđầu tiên được xác định bởi các lệnh giả

tức là 2048. Bộđếm sau đó sẽ tăng lên giá trị kế tiếp tương ứng với 4 byte, 2052

để thực hiện chuyển mã lệnh kế tiếp. Nhưng tại thời điểm đó, biến length không

được chương trình nhận ra nên nó chưa biết giá trị là bao nhiêu. Trong bảng symbol, giá trị của nó tương ứng được ký hiệu “----”. Lệnh tiếp theo sẽ được xử

Cho đến khi trình biên dịch gặp lại length, khi đó giá trị của bộ đếm là 2092. Giá trị của length sẽ được gán với giá trịđếm 2092, tức là nội dung của ô nhớ

length sẽ là nội dung của ô nhớ có địa chỉ là 2092. Như vậy, ô nhớ address và done sẽ có giá trị tương ứng là 2096 và 2088. Nhãn done có giá trị là 2088 vì có 10 lệnh tương ứng 40 byte từ khi có lệnh đầu tiên cho đến khi gặp nhãn done

Sau khi bảng symbol được tạo ra, bước 2 của quá trình chuyển mã sẽ bắt đầu. Chương trình sẽ được đọc lại một lần nữa bắt đầu từ .begin, đồng thời mã lệnh sẽ được tạo ra. Lệnh đầu tiên được tạo ra là lệnh ld sẽ có địa chỉ là 2048. Khi tạo mã lệnh này, ô nhớ length sẽ được đối chiếu với bảng symbol để truy ra giá trị 2096. Với đầy đủ các yếu tốđó, lệnh ld này sẽ được đối chiếu là loại lệnh Memory format và tạo mã tương ứng. Quá trình chuyển mã sẽ được thực hiện tuần tự vào có kết quả tương ứng như hình 5.5

Một phần của tài liệu Bài giảng: Cấu trúc máy tính và ghép nối pot (Trang 76 - 82)