CHƯƠNG 4: NGÔN NGỮ MÁY VÀ HỢP NGỮ
4.2. Máy tính ARC (A RISC Computer)
Để hiểu rừ hơn cỏc nội dung của chương này, chỳng ta sẽ nghiờn cứu một mụ hình cấu trúc dựa trên một kiến trúc vi xử lý mở rộng đã được thương mại hóa SPARC (Scalable Processoer Architecture) được phát triển bởi Sun Microsystems vào những năm 1980. SPARC nhanh chóng trở thành kiến trúc phổ biến từ khi được giới thiệu bởi đây là một hệ thống mở. Kiến trúc đầy đủ của SPARC được hoàn thiện vào khoảng năm 1992. Trong nội dung của chương này, chúng ta sẽ xem xét một thành phần của SPARC là máy tính dựa trên công nghệ RISC, máy tính ARC. ARC là chức năng quan trọng nhất của kiến trúc SPARC nhưng chức năng này lại không có trong các vi xử lý ngày nay
4.2.1. Bộ nhớ của ARC
Máy tính ARC là máy tính 32 bit có bộ nhớ đánh địa chỉ theo byte, tức là máy xử lý các dữ liệu có độ rộng 32 bit, nhưng dữ liệu được lưu trữ là dạng byte.
Đồng thời, độ rộng của tín hiệu địa chỉ là 32 bit được đánh từ thấp đến cao.
Hình 4.4 chính là tổ chức của bộ nhớ trong máy tính ARC, trong đó
• Dải địa chỉ 211 = 2048 thấp nhất trong không gian nhớ được sử dụng làm vùng nhớ dự trữ cho hệ điều hành
• Vùng nhớ dành cho người sử dụng được dùng để nạp chương trình hợp ngữ. Vùng nhớ này bắt đầu từ địa chỉ 2048 đến khoảng stack của hệ thống
• Stack hệ thống bắt đầu từ địa chỉ 231-4 và giảm dần về những địa chỉ thấp hơn. Độ lớn của stack là không xác định trước vì thông thường nó phụ thuộc vào lập trình viên
• Dải địa chỉ từ 231 đến 232-1 được sử dụng để đánh địa chỉ các cổng ngoại vi I/O, với mỗi cổng có địa chỉ hoàn toàn riêng biệt
Máy tính ARC có một vài dạng dữ liệu khác nhau như byte, half word, integer,... nhưng hiện tại, chúng ta sẽ chỉ xem xét đến dạng dữ liệu số nguyên 32 bit. Mỗi số nguyên được lưu trữ trong 4 byte trong bộ nhớ. ARC dựa trên kiến trúc big-endian tức là những byte có trọng số cao sẽ được đánh địa chỉ thấp.
Địa chỉ lớn nhất có thể mà ARC có được là 232-1, do đó tín hiệu địa chỉ lớn nhất mà CPU đưa ra là 232-4
4.2.2. Tập lệnh của ARC
Trước khi tìm hiểu về tập lệnh của ARC, chúng ta sẽ xem xét kỹ hơn về các chức năng của CPU
• Máy tính ARC có 32 thanh ghi 32 bit đa mục đích, cùng với PC và IR
• Thanh ghi trạng thái vi xử lý PSR (Processor Status Register) chứa các thông tin về trạng thái hoạt động của CPU, bao gồm cả các thông tin về kết quả của phép toán trong ALU.
• Mỗi một lệnh được lưu trữ trên 1 word (32 bit)
• ARC là máy tính loại load-store tức là tại 1 thời điểm, nó chỉ cho phép nạp một giá trị vào 1 thanh ghi hoặc lưu 1 giá trị vào một địa chỉ trên bộ nhớ. Các toán hạng trước và sau khi được xử lý bởi ALU đều được lưu trữ trên các thanh ghi. Kiến trúc SPARC có khoảng 200 lệnh, tập lệnh của ARC cũng dựa trên nền lệnh đó. Hình 4.7 mô tả một tập con gồm 15 lệnh của ARC. Các lệnh được thể hiện dưới dạng biểu tượng với ý nghĩa riêng biệt
Biểu tượng
lệnh
Ý nghĩa
Tương tác bộ nhớ
Ld Nạp nội dung thanh ghi từ bộ nhớ St Cất nội dung thanh ghi vào bộ nhớ Phép toán logic Sethi Set 22 bit cao của một thanh ghi
Andcc Thực hiện phép AND từng bit orcc Thực hiện phép OR từng bit Orncc Thực hiện phép NOR từng bit Srl Dịch sang phải
Phép toán số học
Addcc Cộng Điều khiển
luông chương trình
Call Gọi chương trình con
Jmpl Nhảy và liên kết trở về từ chương trình con
Be Rẽ nhánh nếu bằng Bneg Rẽ nhánh nếu nhỏ hơn 0 Bcs Rẽ nhánh nếu có cờ carry Bvs Rẽ nhánh nếu tràn dữ liệu Ba Luôn luôn rẽ nhánh
Hình 4.7. Một vài lệnh cơ bản của ARC
Nhóm lệnh dịch chuyển dữ liệu bao gồm 2 lệnh ld và st là 2 lệnh duy nhất cho phép truy cập vào bộ nhớ hệ thống. Lệnh sethi sẽ định lại giá trị của 22 bit cao trong 1 thanh ghi theo một giá trị định trước.
Nhóm lệnh toán học và lệnh logic gồm các lệnh andcc, orcc, orncc được sử dụng để thực hiện các phép toán AND, OR, NOR theo từng bit của các toán hạng. Một trong 2 toán hạng bắt buộc phải là 1 thanh ghi. Kết quả phép toán sẽ được đặt vào 1 thanh ghi. Lệnh dịch chuyển dữ liệu srl được sử dụng để dịch phải nội dung của một thanh ghi đồng thời sẽ thêm chuỗi các con số 0 vào những bit tận cùng phía bên trái. Lệnh sra (không được mô tả trong hình 4.7) sẽ dịch nội dung các bit trong thanh ghi sang bên phải, đưa nội dung các bit LSB quay trở về vị trí tương ứng thành các bit MSB.
Nhóm lệnh điều khiển bao gồm 2 lệnh chủ yếu là lệnh call và jmpl. Đây là cặp lệnh được sử dụng để gọi chương trình con và nhảy từ chương trình con trở về chương trình chính. Những lệnh như be, bneg, bcs, bvs và ba còn có tên là nhóm lệnh rẽ nhánh. Những lệnh này sẽ kiểm tra nội dung của thanh ghi trạng thái PSR và rẽ chương trình sang các nhánh tương ứng. Điều này có tác dụng giống như các lệnh goto, if-then-else hay do-while trong các ngôn ngữ bậc cao
4.2.3. Cú pháp lệnh của ARC
Mỗi một ngôn ngữ hợp ngữ đều có cú pháp riêng của nó. Chúng ta sẽ tìm hiểu cú pháp của hợp ngữ SPARC, thể hiện trên hình 4.8
Hình 4.8. Cú pháp của ARC
Cú pháp bao gồm 4 thành phần: trường nhãn lệnh có thể không có, trường tên lệnh, các toán hạng nguồn và toán hạng đích nếu có, và cuối cùng là trường lời giải thích cho lệnh đó. Trường giải thích có ý nghĩa chủ yếu là để giúp người lập trình ghi nhớ các lệnh đã viết nên nó có thể có hoặc không.
Nhãn trong cú pháp của ARC có thể là một chuỗi ký tự bất kỳ, tuy nhiên nó phải thỏa mãn là không chứa các ký tự điều khiển, ký tự đặc biệt, hay trùng với một lệnh nào đó
Các thanh ghi toán hạng nguồn và đích trong ARC bao gồm 32 thanh ghi được ký hiệu từ r0 đến r31. 32 thanh ghi này có độ rộng dữ liệu là 32 bit trong đó
Hình 4.9. Các thanh ghi trong ARC mà người sử dụng có thể truy cập thanh ghi số 0 %r0 luôn có giá trị là 0 và giá trị này luôn luôn không đổi. Thanh ghi %r14 và %r15 có thêm chức năng là thanh ghi con trỏ stack và thanh ghi liên kết. Ngoài 32 thanh ghi này, trong ARC còn có thêm các thanh ghi PC là thanh ghi đếm chương trình, thanh ghi trạng thái PSR.
Các toán hạng trong cú pháp lệnh ARC được phân cách nhau bởi dấu phẩy.
Toán hạng đích luôn là toán hạng đứng tận cùng phía bên tay phải.
4.2.4. Cấu trúc ngôn ngữ máy của ARC
Cấu trúc ngôn ngữ máy định nghĩa ý nghĩa của từng bit trong câu lệnh. Tức là nó định nghĩa từng trường trong câu lệnh, độ lớn của từng trường dữ liệu đó và tác động của từng bit lên hệ thống. Có tất cả 5 cấu trúc trong ARC là SETHI, branch, call, arithmetic và memory
Hình 4.10. Cấu trúc lệnh trong ARC
Mỗi một lệnh được biểu diễn bằng một tên riêng và một mã lệnh (Opcode). Mỗi một cấu trúc lệnh có thể có nhiều hơn một trường mã lệnh với mục đích là để thể hiện rừ ràng hơn nội dung, nhiệm vụ, và hoạt động của lệnh.
Cụ thể như sau
• 2 bit tận cùng phía bên trái của mỗi một lệnh là trường op (opcode) được sử dụng để nhận diện cấu trúc lệnh. Cấu trúc SETHI và Branch có cùng giá trị là 00 trong trường này. Cấu trúc SETHI và Branch được phân biệt với nhau ở trường op2 trong đó giá trị 010 tương ứng với Branch và 100 tương ứng với cấu trúc SETHI. Ngoài ra bit thứ 29 trong cấu trúc Branch luôn luôn là 0. Trong khi đó, 5 bit rd trong cấu trúc SETHI chứa thanh ghi đích của lệnh.
• Trường cond trong cấu trúc Branch nhận diện loại lệnh rẽ nhánh, dựa trên mã điều kiện như z, n, v, và c trong thanh ghi trạng thái PSR. Đối với những lệnh có biểu tượng tận cùng có 2 ký tự
“cc”, nếu kết quả của phép toán là số âm thì bit n sẽ có giá trị là 1.
Tương tự, bit z = 1 nếu kết quả bằng 0 và v=1 nếu tràn. Những lệnh có biểu tượng kết thúc không bằng 2 ký tự “cc” sẽ không có hiệu ứng rẽ nhánh. Trường imm22 và disp22 lưu trữ 22 bit được sử dụng như là toán hạng đối với cấu trúc SETHI và để làm cơ sở tính toán cho lệnh rẽ nhánh trong cấu trúc Branch
• Cấu trúc CALL chỉ bao gồm 2 trường duy nhất là trường op có nội dung 01 và trường disp30 được sử dụng là nơi chứa địa chỉ của chương trình mà nó gọi tới.
• Cấu trúc Arithmetic có op = 10 và cấu trúc Memmory có op = 11 cùng có trường rd để nhận dạng thanh ghi nguồn với lệnh st, hoặc để nhận dạng thanh ghi đích trong các trường hợp lệnh còn lại.
Rs1 và rs2 là các thanh ghi nguồn số 1 và 2. Trường op3 được sử dụng để phân biệt các lệnh (được trình bày như hình 4.10)
• Trường simm13 có 13 bit giá trị tức thì có dấu có thể mở rộng lên 32 bit khi trường i có giá trị bằng 1. Để làm được việc này, bit dấu tức là bit tận cùng bên phải được chép vào một số 32 bit có giá trị bằng số trong trường simm13 tương ứng. Ví dụ, giá trị trường trường simm13 là (1111111110011)2 = (-13)10. Khi đó số nguyên 32 bit tương ứng được tạo ra khi trường i = 1 là (11111111111111111111111111110011)2 = (-13)10.
• Cấu trúc lệnh Arithmetic có 2 toán hạng nguồn và 1 toán hạng đích, tổng cộng là 3 toán hạng. Cấu trúc lệnh Memmory có 2 toán hạng:
một dành cho địa chỉ, một dành cho dữ liệu. Thông thường toán hạng nguồn là địa chỉ
4.2.5. Cấu trúc dữ liệu của ARC
ARC hỗ trợ 12 cấu trúc dữ liệu khác nhau được mô tả như hình 4.11. được chia thành 3 nhóm: số nguyên có dấu, số nguyên không dấu và số dấu phẩy động.
Với các loại cấu trúc dữ liệu này, độ rộng dữ liệu cho phép là 1 byte (8 bit), halfword (16 bit), tagged word (32 bit nhưng chỉ sử dụng 30 bit có trọng số lớn nhất để chứa giá trị), doubleword (64 bit) và quadword (128 bit)
Hình 4.11. Cấu trúc dữ liệu của ARC
Trong thực tế sử dụng, ARC không phân biệt số có dấu và số không dấu. Cả 2 loại này được lưu trữ và tính toán như là số nguyên bù 2. Chúng chỉ khác nhau ở phương pháp biểu diễn. Trong từng trường hợp cụ thể, một giá trị sẽ được giả định là có dấu hoặc không dấu. Khi đó các bit v và c sẽ được sử dụng. Bit c = 1 khi xảy ra hiện tượng tràn của số không dấu, bit v = 1 khi tràn số có dấu.
Trong số tagged word, 2 bit có trọng số nhỏ nhất được sử dụng để biểu thị hiện tượng tràn số
Số dấu phẩy động được sử dụng trong máy tính ARC tuân theo chuẩn IEEE 754-1985 (xem chương 2)
4.2.6. Mô tả các lệnh của ARC
Chúng ta vừa tìm hiểu xong cấu trúc một lệnh. Bây giờ chúng ta sẽ mô tả kỹ hơn 15 lệnh được liệt kê trong hình 4.7. Trong phần nêu chi tiết này, ta sẽ đưa ra chi tiết mã lệnh (Object code) với mục đích chính là để tham khảo. Việc chuyển mã lệnh như thế nào sẽ được chúng ta tìm hiểu chi tiết trong chương kế tiếp
Tên lệnh ld
Mô tả Nạp nội dung của một thanh ghi từ bộ nhớ. Các địa chỉ bộ nhớ phải có giá trị chia hết cho 4 tức là có ranh giới từ. Giá trị địa chỉ sẽ được tính toán bằng cách cộng nội dung của thanh ghi trong trường rs1 hoặc giá trị trong trường simm13 tùy theo từng trường hợp
Ví dụ Ld [x], %r1
Hoặc Ld [x], %r0, %r1
Hoặc Ld %r0+x, %r1
Ý nghĩa Copy nội dung của bộ nhớ địa chỉ là x vào thanh ghi r1
Mã lệnh 11000010000000000010100000010000 (x = 2064)
Tên lệnh st
Mô tả Cất nội dung của thanh ghi vào bộ nhớ. Các địa chỉ bộ nhớ phải có giá trị chia hết cho 4 tức là có ranh giới từ. Địa chỉ sẽ được tính toán bằng cách cộng nội dung của thanh ghi trong trường rs1 với nội dung của thanh ghi trong trường rs2 hoặc nội dung trong trường simm13. Trường rd trong lệnh này được sử dụng để chứa thanh ghi nguồn
Ví dụ st %r1, [x]
Ý nghĩa Copy nội dung của thanh ghi r1 vào bộ nhớ địa chỉ là x
Mã lệnh 11000010001000000010100000010000 (x = 2064)
Tên lệnh sethi
Mô tả Set nội dung của 22 bit cao của thanh ghi lên một giá trị nhất định và đưa 10 bit thấp của thanh ghi đó về 0. Nếu toán hạng là 0 và thanh ghi được sử dụng là r0 thì lệnh này tương đương với lệnh không làm gì cả NOP
Ví dụ sethi 0x304F15, %r1
Ý nghĩa Nạp nội dung (304F15)16 vào 22 bit cao của thanh ghi r1 còn 10 bit thấp xóa về 0
Mã lệnh 00000011001100000100111100010101
Tên lệnh andcc
Mô tả Tính lệnh AND từng bit của 2 toán hạng nguồn và đưa kết quả về toán hạng đích
Ví dụ andcc %r1, %r2, %r3
Ý nghĩa Tính lệnh AND nội dung thanh ghi r1 với thanh ghi r2 và đưa kết quả vào thanh ghi r3
Mã lệnh 10000110100010000100000000000010
Tên lệnh orcc
Mô tả Tính lệnh OR từng bit của 2 toán hạng nguồn và đưa kết quả về toán hạng đích
Ví dụ orcc %r1, 1, %r1
Ý nghĩa Set tất cả các bit trong thanh ghi r1 lên giá trị 1 và đưa kết quả về thanh ghi r1
Mã lệnh 10000010100100000110000000000001
Tên lệnh Srl
Mô tả Thực hiện phép dịch sang phải từ 0 tới 31 bit. Những bit ở phía bên trái sẽ được điền đầy bởi giá trị 0
Ví dụ srl %r1, 3, %r2
Ý nghĩa Dịch nội dung thanh ghi r1 sang phải 3 bit, lưu kết quả vào thanh ghi r2
Mã lệnh 10000101001100000110000000000011
Tên lệnh addcc
Mô tả Cộng 2 toán hạng nguồn và đưa kết quả về toán hạng đích với phép cộng 2 số bù 2
Ví dụ addcc %r1, 5, %r1
Ý nghĩa Cộng 5 vào thanh ghi r1
Mã lệnh 10000010100000000110000000000101
Tên lệnh call
Mô tả Gọi chương trình con, lưu địa chỉ của lệnh đang thực hiện vào thanh ghi %r15. Trong mã lệnh, trường disp30 trong cấu trúc call chứa 30 bit địa chỉ mà nó trỏ tới. Địa chỉ mà máy tính xử lý kế tiếp là địa chỉ có giá trị 4 x disp30. Chú ý rằng disp30 cũng có thể là số âm
Ví dụ call sub_r Ý nghĩa Gọi chương trình con sub_r
Mã lệnh 01000000000000000000000000011001
Tên lệnh jmpl
Mô tả Nhảy về chương trình chính từ chương trình con và cất địa chỉ của lệnh đang thực hiện về thanh ghi đích
Ví dụ jmpl %r15 + 4, %r0
Ý nghĩa Trở về từ chương trình chính. Địa chỉ trước kia được lưu ở thanh ghi %r15 sẽ được khôi phục và lệnh kế tiếp được thực thi là ở địa chỉ %r15+4.Địa chỉ hiện tại sẽ được bỏ đi
Mã lệnh 10000001110000111110000000000100
Tên lệnh be
Mô tả Nếu bit z = 1 thì chương trình thì chương trình nhảy tới địa chỉ 4 x disp22 trong cấu trúc rẽ nhánh. Nếu z = 0 thì lệnh nhảy tới lệnh kế tiếp sau lệnh be
Ví dụ be label
Ý nghĩa Nhảy tới nhãn label nếu z = 1
Mã lệnh 00000010100000000000000000000101
Tên lệnh bneg
Mô tả Nếu bit n = 1 thì chương trình thì chương trình nhảy tới địa chỉ 4 x disp22 trong cấu trúc rẽ nhánh. Nếu n = 0 thì lệnh nhảy tới lệnh kế tiếp sau lệnh bneg
Ví dụ bneg label
Ý nghĩa Nhảy tới nhãn label nếu n = 1
Mã lệnh 00001100100000000000000000000101
Tên lệnh bcs
Mô tả Nếu bit c = 1 thì chương trình thì chương trình nhảy tới địa chỉ 4 x disp22 trong cấu trúc rẽ nhánh. Nếu c = 0 thì lệnh nhảy tới lệnh kế tiếp sau lệnh bcs
Ví dụ bcs label
Ý nghĩa Nhảy tới nhãn label nếu c = 1
Mã lệnh 00001010100000000000000000000101
Tên lệnh bvs
Mô tả Nếu bit v = 1 thì chương trình thì chương trình nhảy tới địa chỉ 4 x disp22 trong cấu trúc rẽ nhánh. Nếu v = 0 thì lệnh nhảy tới lệnh kế tiếp sau lệnh bvs
Ví dụ bvs label
Ý nghĩa Nhảy tới nhãn label nếu v = 1
Mã lệnh 00001110100000000000000000000101
Tên lệnh ba
Mô tả Nhảy không điều kiện đến địa chỉ 4 x disp22 trong cấu trúc rẽ nhánh
Ví dụ ba label
Ý nghĩa Nhảy không điều kiện tới nhãn label. Trong mã lệnh dưới đây, nhãn là là vùng nhớ trước vùng nhớ hiện tại 5 word
Mã lệnh 00010000101111111111111111111011