TRƯỜNG ĐẠI HỌC HÀNG HẢI VIỆT NAM
BÁO CÁO BÀI TẬP LỚN
MÔN HỌC KIẾN TRÚC MÁY TÍNH TIÊN TIÊN
Đề tài: TÌM HIỂU KIẾN TRÚC MIPS
GVHD : TS. Nguyễn Trọng Đức
Nhóm 01 : Lê Hoàng Dương
Lê Quyết Tiến
Đặng Trung Hiếu
Nguyễn Hoàng Thùy Trang
Bùi Thị Hương
Hải Phòng, tháng 5 năm 2014
CHƯƠNG I: KIẾN TRÚC CISC VÀ RISC
1.1. Kiến trúc CISC
CISC (Complex Instruction Set Computer) - Kiến trúc với tập lệnh phức tạp
được nghĩ ra từ những năm 1960. Vào thời kỳ này, người ta nhận thấy các chương
trình dịch khó dùng các thanh ghi, và các vi lệnh thì được thực hiện nhanh hơn các
lệnh đồng thời phải làm giảm độ dài các chương trình. Các đặc tính này khiến người
ta ưu tiên chọn các kiểu ô nhớ - ô nhớ và ô nhớ - thanh ghi, với những lệnh phức
tạp và dùng nhiều kiểu định vị. Điều này dẫn tới việc các lệnh có chiều dài thay đổi
và như thế thì dùng bộ điều khiển vi chương trình (Microprogramme) là hiệu quả
nhất.
Một số đặc điểm của kiến trúc CISC:
- Lệnh có độ dài thay đổi, phức tạp, có thể bao gồm một vài phép toán nhỏ,
tuy nhiên lệnh của CISC gần với ngôn ngữ lập trình bậc cao.
- Có nhiều chế độ địa chỉ phức tạp.
- Hỗ trợ các loại dữ liệu phức tạp.
- Một lệnh có thể được thực hiện trên nhiều chu kỳ.
- Sử dụng kỹ thuật điều khiển vi chương trình.
Bộ xử lý IBM 370/168 DEC 11/780 iAPX 432
Năm sản xuất 1973 1978 1982
Số lệnh 208 303 222
Bộ nhớ vi CT 420 KB 480 KB 64 KB
Chiều dài lệnh
(tính bằng bit)
16 - 48 16 - 456 6 - 321
Kỹ thuật chế tạo ECL - MSI TTl - MSI NMOS VLSI
Cách thực hiện lệnh
Thanh ghi- thanh ghi
Thanh ghi - bộ nhớ
Bộ nhớ - bộ nhớ
Thanh ghi - thanh ghi
Thanh ghi - bộ nhớ
Bộ nhớ - bộ nhớ
Ngăn xếp
Bộ nhớ- bộ nhớ
Dung lượng cache 64 KB 64 KB 0
Hình 1.1 Thông số một vài máy CISC
1.2. Kiến trúc RISC
RISC (Reduce Instruction Set Computer) là một dạng của kiến trúc vi xử lý,
trong đó phương pháp thiết kế các bộ vi xử lý theo hướng đơn giản hóa tập lệnh,
thời gian thực thi tất cả các tập lệnh đều như nhau. Đầu tiên, các dự án về RICS
được bắt đầu từ IBM, Stanford và UC Berkeley vào cuối những năm 70 đầu những
năm 80. Hiện nay, các bộ vi xử lý phổ biến là ARM, SuperH, MIPS, SPARC, DEC
Alpha, PA-RICS, PIC và PowerPC của IBM.
Một số đặc điểm của kiến trúc RISC:
- Một lệnh thực thi trong 1 chu kỳ.
- Định dạng lệnh đơn giản, độ dài lệnh cố định nên dễ giải mã lệnh
- Các thanh ghi chung mục đích có thể sử dụng trong nhiều ngữ cảnh nên dễ
thiết kế phần mềm biên dịch.
- Chế độ địa chỉ đơn giản, các chế độ địa chỉ phức tạp được thực hiện thông
qua chuỗi lệnh số học và lệnh nạp/ghi.
- Thuận tiện cho việc thiết kế song song.
- Chú trọng các thao tác với thanh ghi.
Bộ xử lý IBM 801 RISC1 MIPS
Năm sản xuất 1980 1982 1983
Số lệnh 120 39 55
Dung lượng bộ nhớ vi
chương trình
0 0 0
Độ dài lệnh (tính bằng
bit)
32 32 32
Kỹ thuật chế tạo ECL MSI NMOS VLSI NMOS VLSI
Cách thực hiện lệnh Thanh ghi-thanh ghi Thanh ghi-thanh ghi Thanh ghi-thanh ghi
Hình 1.1 Thông số một vài máy RISC
1.3. So sánh giữa CISC và RISC
RISC CISC
Ưu điểm
- Diện tích của bộ xử lý dùng cho
bộ điều khiển giảm từ 60% (cho
các bộ xử lý CISC) xuống còn 10%
(cho các bộ xử lý RISC). Như vậy
có thể tích hợp thêm vào bên trong
bộ xử lý các thanh ghi, các cổng
vào ra và bộ nhớ cache.
- Tốc độ tính toán cao nhờ vào việc
giải mã lệnh đơn giản, nhờ có
nhiều thanh ghi (ít thâm nhập bộ
nhớ), và nhờ thực hiện kỹ thuật ống
dẫn liên tục và có hiệu quả (các
lệnh đều có thời gian thực hiện
giống nhau và có cùng dạng).
- Thời gian cần thiết để thiết kế bộ
điều khiển là ít. Điều này góp phần
làm giảm chi phí thiết kế.
- Bộ điều khiển trở nên đơn giản và
gọn làm cho ít rủi ro mắc phải sai
sót mà ta gặp thường trong bộ điều
khiển.
- Chương trình ngắn hơn so với kiến
trúc RISC
- Số lệnh để thực hiện chương trình ít
hơn. Khả năng thâm nhập bộ nhớ dễ
dàng hơn.
- Các bộ xử lý CISC trợ giúp mạnh hơn
các ngôn ngữ cao cấp nhờ có tập lệnh
phức tạp.
- Có nhiều chế độ địa chỉ.
- Các tính năng có dấu phẩy động
mạnh.
- Tăng khả năng của Cache.
Nhược
điểm
Các chương trình dài ra so với
chương trình viết cho bộ xử lý
CISC. Điều này do các nguyên
nhân sau :
- Cấm thâm nhập bộ nhớ đối với tất
cả các lệnh ngoại trừ các lệnh đọc
và ghi vào bộ nhớ. Do đó ta buộc
phải dùng nhiều lệnh để làm một
công việc nhất định.
- Cần thiết phải tính các địa chỉ
hiệu dụng vì không có nhiều cách
- Diện tích của bộ xử lý dùng cho bộ
điều khiển lớn. Giảm khả năng tích hợp
thêm vào vi xử lý.
- Tốc độ tính toán còn chậm. Thời gian
xây dựng xong bộ vi xử lý là lâu hơn
do các câu lệnh phức tạp nên khả năng
định vị.
- Tập lệnh có ít lệnh nên các lệnh
không có sẵn phải được thay thế
bằng một chuỗi lệnh của bộ xử lý
RISC.
- Các chương trình dịch gặp nhiều
khó khăn vì có ít lệnh làm cho có ít
lựa chọn để diễn dịch các cấu trúc
của chương trình gốc. Sự cứng
nhắc của kỹ thuật ống dẫn cũng gây
khó khăn.
- Có ít lệnh trợ giúp cho ngôn ngữ
cấp cao.
xảy ra rủi ro nhiều.
CHƯƠNG II: KIẾN TRÚC MIPS
2.1. Giới thiệu về MIPS:
MIPS - Microprocessor without Interlocked Pipeline Stages: là một kiến
trúc xử lý kiểu RISC được phát triển bởi công ty MIPS technologies. Các bộ xử lý
MIPS được phát triển như là một phần của chương trình nghiên cứu VLSI ở trường
đại học Stanford đầu những năm 80. Năm 1984, Hennessy rời khỏi trường Stanford
để xây dựng hệ thống máy tính MIPS sau khi nhận ra nhu cầu thương mại tương lai
của thiết kế. Phiên bản MIPS R2000 đầu tiên ra đời năm 1985, sau đó là phiên bản
MIPS R3000 năm 1988.
Kiến trúc MIPS là kiến trúc các thanh ghi. Tất cả các phép toán số học và
logic đều chỉ xoay quanh thanh ghi (hay các hằng số được lưu trữ như là một thành
phần của lệnh). Kiến trúc MIPS cũng bao gồm một số các câu lệnh đơn giản dùng
để đọc dữ liệu từ bộ nhớ vào thanh ghi và ghi dữ liệu từ thanh ghi sang bộ nhớ. Vì
vậy kiến trúc MIPS được gọi là kiến trúc nap/lưu trữ,trong kiến trúc nạp/lưu trữ chỉ
có những câu lệnh có thể truy cập vào bộ nhớ là các câu lệnh nạp/lưu trữ còn các
câu lệnh khác chỉ có thể truy cập tới thanh ghi.
Kiến trúc tập lệnh MIPS (ISA) được phát triển từ kiến trúc tập lệnh MIPS I
đến kiến trúc tập lệnh MIPS V. Vào cuối những năm 1990, kiến trúc MIPS đã được
thiết kế xung quanh hai kiến trúc cơ bản sau:
• MIPS32 cho kiến trúc 32-bit. Kiến trúc MIPS-32bit dựa vào tập lệnh MIPS
II ISA với một vài lệnh được thêm vào từ tập lệnh MIPS III đến tập lệnh
MIPS V ISA.
• MIPS64 cho kiến trúc 64-bit , kiến trúc MIPS-64bit thì dựa vào tập lệnh của
MIPS V ISA.
Ngày này, kiến trúc MIPS được sử dụng rộng dãi trong các hệ thống nhúng
như Series2 TiVo, các thiết bị Window CE, các bộ định tuyến Cisco, các thiết bị
chơi game như Nitendo 64, Sony PlayStation MIPS được thiết kế một bộ tập lệnh
đơn giản dễ hiểu nên việc nghiên cứu kiến trúc MIPS rất hữu ích cho việc nghiên
cứu về kiến trúc máy tính.
2.2. Các thành phần cơ bản của kiến trúc MIPS:
Kiến trúc MIPS bao gồm các thành phần sau:
• MIPS instruction set architecture (ISA) - Kiến trúc tập lệnh MIPS: Định
nghĩa một tập các câu lệnh 32bit và 64 bit để đảm bảo tương thích với mọi
bộ xử lý áp dụng kiến trúc MIPS. Tập lệnh MIPS bao gồm tổng cộng 111
câu lệnh ở hệ 32 bit, ví dụ như một câu lệnh MIPS dưới đây:
• MIPS privileged resource architecture(PRA)-Kiến trúc tài nguyên phân
quyền: Đưa ra một tập các môi trường đảm bảo cho ISA hoạt động. PRA
cung cấp các cơ chế cần thiết để quản lý các tài nguyên của bộ xử lý: bộ nhớ
ảo, cache, các ngoại lệ…
• MIPS application specific extension(ASE)-Các thành phần mở rộng tùy
chọn cho ứng dụng: Cung cấp các chức năng nâng cao được thiết kế riêng
biệt cho các chức năng khác nhau.
• MIPS user defined instruction (UDI)-Câu lệnh được người dùng định
nghĩa: Đây là các câu lệnh đặc biệt cho các ứng dụng khác nhau với các mục
đích khác nhau khi một bộ xử lý áp dụng kiến trúc MIPS.
Trên thực tế máy tính làm việc thông qua việc lấy lệnh ngôn ngữ máy từ bộ nhớ,
giải mã và tính toán chúng. Ngôn ngữ máy và các giá trị sẽ được tính toán và mã
hóa thành mã nhị phân. Máy tính chỉ làm việc với các giá trị nhị phân, để thực hiện
xây dựng một kiến trúc máy tính sử dụng kiến trúc MIPS thì các thành phần cơ bản
phải bao gồm là:
o Program counter (PC): con trỏ chương trình.
o Memory : Bộ nhớ.
o Instruction Register: tập các thanh ghi lệnh.
o Register File: tập các thanh ghi.
o ALU: Khối đơn vị số học và logic.
o CU: khối đợn vị kiểm soát
Tất cả các thành phần ngoại trừ CU, thì đều được kết nối với nhau bằng Bus. Hầu
hết các bus của kiến trúc Mips đều có kích thước 32-bits. Dưới đây là một minh họa
về thành phần và đường đi của dữ liệu trong kiến trúc MIPS. Ngày nay việc cài đặt
theo kỹ thuật đường ống (Pipeline) và siêu vô hướng (Superscalar) là chung nhất
cho các bộ xử lý hiệu năng cao.
Hình 2.1 Thành phần và đường đi dữ liệu trong kiến trúc MIPS
2.3. Tập các thanh ghi trong kiến trúc MIPS:
Kiến trúc MIPS cung cấp một tập hợp gồm các thanh ghi chung, các thanh
ghi dấu phẩy động FPU, thanh ghi chương trình (hay còn được gọi là con trỏ
chương trình PC), và các thanh ghi đặc biệt HI, LO. Kích thước của thanh ghi trong
kiến trúc MIPS có thể là 32 bits ứng với MIPS32 hoặc 64 bits ứng với MIPS 64.
Hình 2.2 Mô tả thành phần thanh ghi trong MIPS R2000
2.3.1. Thanh ghi CPU
2.3.1.1. Tập thanh ghi MIPS (32 thanh ghi)
Tên Số Usage Ý nghĩa
$zero $0 Constant 0 Hằng số 0
$at $1 Reserved for assembler Asembler Temporary
$v0-$v1 $2-$3
Expression evaluation
and results of a function
Giá trị trả lại của hàm hoặc biểu thức
$a0-$a3 $4-$7 Argument Các tham số của hàm
$t0-$t7 $8-$15
Temporary (not preserved
across call)
Thanh ghi tạm
$s0-$s7 $16-$23
Saved temporary
(preserved across call)
Thanh ghi lưu trữ
$t8-$t9 $24-$25
Temporary (not preserved
across call)
Thanh ghi tạm
$k0-$k1 $26-$27 Reserved for OS kernel Dự trữ cho nhân OS
$gp $28 Pointer to global area Con trỏ toàn cục
$sp $29 Stack pointer Con trỏ stack
$fp $30 Frame pointer Con trỏ frame
$ra $31
Return address (used by
function call)
Địa chỉ trả về
- Thanh ghi zero( có tên là $zero:) chứa giá trị 0, không có một giá trị nào được ghi
vào thanh ghi zero.
- Thanh ghi 1( có tên là $at): được gọi cho hợp ngữ tạm thời, thanh ghi này dành
cho tính toán các lệnh marco, và không nên được sử dụng cho các chương trình hợp
ngữ.
- Các thanh ghi $k0 và $k1: được sử dụng bởi các nhân( kernel) của hệ điều hành,
và không nên bị thay đổi bởi chương trình người dùng.
- Thanh ghi cuối cùng $31 ($ra): được sử dụng giống như là một thanh ghi liên kết
bởi lệnh nhảy và lệnh liên kết, cái mà sẽ được sử dụng để gọi một thủ tục. Thanh
ghi $31 được sử dụng để ghi nhớ địa chỉ trả về của một thủ tục được gọi.
- Các thanh ghi $v0 và $v1: dùng để lưu trữ giá trị trả về của hàm.
- Các thanh ghi $t0-$t9: là các thanh ghi có nhớ lời gọi, dùng cho các giá trị tạm
thời mà không cần phải nhớ mỗi khi có lời gọi.
- Các thanh ghi $s0-$s7: là các thanh ghi có nhớ lời gọi, dùng cho các giá trị
không thay đổi mỗi khi có lời gọi.
- Thanh ghi $sp: là con trỏ stack, trỏ tới đỉnh của một stack.
- Thanh ghi $rp: là con trỏ frame.
- Thanh ghi $ra: ghi lại địa chỉ trả về mỗi khi có lời gọi hàm.
- Thanh ghi $gp: là con trỏ toàn cục trỏ tới vị trí giữa của khối bộ nhớ 64K vùng
heap, nơi chứa các biến và hằng số toàn cục.
2.3.1.2. Thanh ghi đặc biệt (2 thanh ghi)
Hai thanh ghi đặc biệt được gọi là thanh ghi HI và thanh ghi LO, chúng được
sử dụng để kiểm soát kết quả của một lệnh thực hiện nhân hoặc chia số nguyên.
Thao tác nhân của MIPS có kết quả chứa trong 2 thanh ghi HI và LO. Bit 0-31
thuộc LO và 32-63 thuộc HI.
2.3.1.3. Thanh ghi chương trình(PC)
Sau khi một chương trình được viết như là một chương trình bằng ngôn ngữ
hợp ngữ sử dụng một trình tạo văn bản, chương trình được chuyển thành mã máy
bằng một chương trình sử dụng gọi một trình biên dịch hợp ngữ. Mã của ngôn ngữ
máy được ghi vào một file trên đĩa. Khi mà một người muốn thực hiện chương trình
này, một chương trình sử dụng khác, gọi một đường dẫn nạp chương trình, sẽ nạp
và liên kết với tất cả các khối ngôn ngữ máy cần thiết bên trong bộ nhớ chính. Các
lệnh riêng biệt sẽ được ghi nhớ tuần tự vào bộ nhớ. Con trỏ chương trình( PC) là
một thanh ghi được khởi tạo bởi hệ điều hành đến địa chỉ của lệnh đầu tiên của
chương trình trong bộ nhớ. Chú ý rằng địa chỉ trong con trỏ chương trình được
gửi đến đầu vào địa chỉ của bộ nhớ thông qua một bus. Sau khi một lệnh được
lấy từ bộ nhớ và được nạp vào thanh ghi lệnh( IR) con trỏ PC sẽ được tăng để
CPU có được địa chỉ cho lệnh tuần tự tiếp theo cho quá trình lấy lệnh.
2.3.1.4. Các thanh ghi lệnh
Thanh ghi lệnh IR là thanh ghi 32-bits dùng để nắm bản sao chép của lệnh
được gọi đến gần đây nhất. Trong kiến trúc MIPS thì có 3 định dạng lệnh khác nhau
được định nghĩa: định dạng R, định dạng I và định dạng J.
2.3.2. Thanh ghi FPU
Kiến trúc MIPS đưa ra các thanh ghi FPU sau:
• 32 thanh ghi dấu chấm phẩy động. Các thanh ghi này có độ dài 32-bit nếu là
bộ FPU 32-bit hoặc 64 bit nếu là bộ FPU 64-bit.
• 5 thanh ghi điều khiển FPU dùng để nhận diện và quản lý FPU
• 8 bộ mã điểu khiển số dấu chấm động là các thành phần của thanh ghi
FCSR,FP control/status register.
2.3.2.1. Dữ liệu trong thanh ghi FPU
FPU hỗ trợ hai dạng dữ liệu: số dấu chấm động và số dấu chấm tĩnh:
- Số dấu chấm động độ chính xác đơn và kép được định nghĩa theo chuẩn IEEE.
- Số dấu chấm tĩnh là các số nguyên có dấu hỗ trợ bởi kiến trúc CPU.
Các dạng số dấu chấm động được cung cấp bởi FPU là:
- Số dấu chấm động chính xác đơn 32-bits (kiểu S):
S (bit dấu) Phần mũ Phần lẻ
1bit 8 bit 23 bit
- Số dấu chấm động với độ chính xác kép (kiểu D) 64-bits:
S (bit dấu) Phần mũ Phần lẻ
1bit 11 bit 52 bit
- Số dấu chấm động đơn kẹp đôi (kiểu PS) 64-bits:
S Phần mũ Phần lẻ S phần mũ phần lẻ
1 bit 8 bit 23 bit 1 bit 8 bit 23 bit
Các định dạng số dấu chấm tĩnh hỗ trợ bởi FPU:
- Kiểu Word 32-bits:
S Interger
1 bit 31 bit
- Kiểu LongWord (kiểu L) 64-bits:
S Interger
1 bit 63 bit
2.3.2.2. Các thanh ghi đa năng
Trong phiên bản 1 của kiến trúc số dấu chấm động chỉ có trong kiến trúc
MIPS64 nhưng ở phiên bản 2 thì chúng được hỗ trợ trong cả kiến trúc MIPS32.
FPU 32-bits có 32 thanh ghi 32-bits FPRs, mỗi thanh chứa một kiểu dữ liệu
32 bits. Kiểu xác định kép (Double-pricesion-kiểu D) được lưu trữ trong các cặp
thanh ghi chẵn, lẻ của FPRs, còn số nguyên dài (kiểu L) và kiểu Paired single (kiểu
PS) thì không được hỗ trợ.
FPU 64-bits có 32 thanh ghi 64 bits số dấu chấm động, mỗi thanh ghi có thể
chứa mọi kiểu dữ liệu. Để tương thích với FPU 32-bits, bit FR trong thanh ghi CP0
Status được sử dụng trong MIPS64 phiên bản 1 hoặc bất kỳ bộ xử lý phiên bản 2
nào hỗ trợ FPU 64-bits để điểu chỉnh FPU sang trạng thái mà các thanh ghi FPRs
được coi như các thanh ghi 32 bits, và sẽ lưu trữ các kiểu dữ liệu giống FPRs 32-
bits.
o FR =0 : chế độ 64-bits
o FR =1 : chế độ 32-bits. Khi đó chỉ 32 bits đầu được sử dụng, 32 bits sau
không dùng.
Hình 2.3. Thanh ghi đa năng
2.3.2.3. Các thanh ghi điều khiển
Có 5 thanh ghi điều khiển trong kiến trúc MIPS:
- FIR,FP Implementation and Revision Register.
- FCCR, FP condition codes Register.
- FEXR, FP Exception Register.
- FENR, FP Enables Register.
- FCSR, FP control/Status Register.
FCCR, FEXR, FENR truy cập tới FCSR thông qua lệnh CTC1 và CFC1. Các
thanh ghi này được dùng nếu chế độ dấu chấm động được sử dụng.
2.4. Bộ nhớ
Tất cả các bộ xử lý hiện đại đều làm việc với bộ nhớ Cache. Bộ nhớ Cache
được đặt trên chip CPU. Bộ nhớ Cache cung cấp bộ nhớ nhanh để truy cập đến các
lệnh và dữ liệu thay vì CPU phải truy cập vào bộ nhớ chính. Bộ nhớ Cache có chức
năng giống như là nơi mà thông tin được lưu trữ và lấy ra theo từ nhớ ( word), một
từ nhớ (word) là tương ứng với 32-bits. Mỗi vùng trong bộ nhớ có 32-bits địa chỉ.
Trong kiến trúc MIPS, địa chỉ của bộ nhớ được đánh từ 0 đến 4,294,967,295. Trong
kiến trúc MIPS thì một từ nhớ là 32-bits và một byte là 8-bits. Như vậy trong kiến
trúc MIPS thì một từ bao gồm 4-Bytes, và đơn vị địa chỉ nhỏ nhất có thể của thông
tin được tham biến trong bộ nhớ là một byte. Địa chỉ của byte đầu tiên trong từ nhớ
cũng là địa chỉ của từ nhớ. Tất cả các lệnh trong kiến trúc MIPS đều có 32-bits độ
dài. Vì vậy con trỏ chương trình được tăng lên 4 sau khi mỗi lệnh được thực
hiện.
2.5. Kiểu dữ liệu và cách thức đánh địa chỉ
2.5.1. Kiểu dữ liệu:
Ta xét bộ xử lý R4000, đây là một bộ xử lí thiết kế theo kiến trúc MIPS, sử
dụng 4 định dạng dữ liệu là:
• Kiểu Doubleword với 64-bit.
• Kiểu Word với 32-bit.
• Kiểu Halfword với 16-bit.
• Kiểu Byte với 8-bit.
Trong đó thì trật tự sắp xếp của các byte trong các kiểu định dạng Halfword,
word và Doubleword có thể được thiết lập theo kiểu đầu to (big-endian) hoặc kiểu
đầu nhỏ (little-endian). Khi mà bộ xử lí được thiết lập theo kiểu đầu to, thì byte số
0 là byte có ý nghĩa cao nhất và ngược lại, đối với kiểu đầu nhỏ thì byte số 0 là
byte có ý nghĩa thấp nhất.
Hình 2.4. Kiểu big-endian trong kiểu dữ liệu Word (32-bits)
Hình 2.5. Kiểu little-endian trong kiểu dữ liệu Word (32-bits)
Hình 2.6: Dữ liệu kiểu đầu nhỏ trong Doubleword.
Hình 2.7. Dữ liệu đầu to trong Doubleword
2.5.2. Cách thức đánh địa chỉ:
Kiến trúc MIPS được biết đến với tập lệnh máy tính đơn giản nên các nhà
thiết kế kiến trúc MIPS đã cung cấp cho chúng ta một tập hợp các lệnh cơ bản.
Trong trường hợp muốn gọi một giá trị từ bộ nhớ chính hoặc ghi một giá trị vào bộ
nhớ chính, chỉ một phương thức đánh địa chỉ được cài đặt trong phần cứng của máy
tính. Phương pháp đánh địa chỉ này được hiểu như là phương pháp đổi chỗ nhiều
địa chỉ cơ sở. Phương thức đánh địa chỉ đưa ra cách thức để biết được làm thế nào
mà một toán hạng được xác định.
Như chúng ta đã biết thì đối với một toán hạng nó có thể có 3 vị trí: trong
thanh ghi, trong bộ nhớ, hoặc nằm ngay trong phần của câu lệnh và được hiểu như
là một hắng số. Việc xác định một hằng số được coi như một toán hạng gọi là
phương thức đánh địa chỉ tức thời. Tương tự như vậy, việc xác định một toán
hạnh được lưu trong thanh ghi gọi là phương thức đánh địa chỉ thanh ghi. Mọi bộ
xử lý đều chấp nhận hai phương thức đánh địa chỉ này. Sự khác nhau giữa bộ xử lí
RISC và CISC là làm thế nào chúng xác định được một toán hạng trong bộ nhớ.
Việc thiết kế CISC tập trung vào sự biến đổi rộng rãi của phương thức đánh địa chỉ
bộ nhớ. Còn việc thiết kế RISC chỉ chấp nhận duy nhất một hoặc nhiều nhất là hai
kiểu phương thức đánh địa chỉ trong câu lệnh nạp và ghi bộ nhớ. Tất cả các kiến
trúc MIPS chấp nhận hai phương thức đánh địa chỉ sau đây:
• Địa chỉ của toán hạng được tính toán bởi phép cộng nội dung của một thanh
ghi và một hằng số. Nếu như là hằng số bằng 0, nội dung của thanh ghi được
xử lý giống như là địa chỉ của một toán hạng. Trong phương thức này, địa
chỉ bộ nhớ được tính toán giống như sau:
Address = contents of a register + constant.
• Địa chỉ của toán hạng bộ nhớ được tính toán bởi phép cộng nội dung của
hai thanh ghi. Nếu như một thanh ghi là bằng 0, phương thức đánh địa chỉ
này trở thành giống như phương thức trên với hằng số 0. Trong phương thức
này, địa chỉ được tính toán như sau:
Address = contents of register 1+ contents of register 2.
Kiến trúc Mips là một kiến trúc nạp và ghi ( Load/Store architecture), điều
này có nghĩa là tất cả các lệnh truy cập vào bộ nhớ chính đều là các lệnh nạp và ghi(
Load/store instruction). Một lệnh nạp truy cập giá trị từ bộ nhớ và đặt một bản copy
của giá trị tìm thấy trong bộ nhớ vào một trong số tập hợp các thanh ghi.
Ví dụ: Lw $s1,8($a0)
Lệnh này sẽ tính toán địa chỉ thật của vùng nhớ được truy cập bởi thao tác cộng nội
dung của thanh ghi $a0 ( thanh ghi cơ sở) và 8 giá trị hằng (offset). Một bản copy
của giá trị truy cập từ bộ nhớ chính tại địa chỉ thực sẽ được nạp vào trong thanh ghi
$s1. Một lệnh giả mã tương đương như sau: $s1 = Mem[$a0 + 8]
Chú ý rằng trong ví dụ này thì địa chỉ cơ sở là giá trị của thanh ghi $a0, và số đổi
chỗ là giá trị hằng 8. Giá trị cở sở sẽ luôn luôn là giá trị của một trong những thanh
ghi register file. Và giá trị di chuyển luôn luôn là một giá trị hằng, giá trị hằng này
có thể nhân các giá trị từ -32,768 đến +32,767. Trong trường hợp lệnh nạp một
từ nhớ, địa chỉ thực cần phải là một con số mà là kết quả của một phép nhân với 4,
bởi vì một từ nhớ bao giờ cũng bao gồm 4 byte.
CHƯƠNG III: TẬP LỆNH TRONG MIPS
Tập lệnh (Instruction Set) luôn là phần thiết yếu không thể thiếu của bất kì
một kiến trúc nào. Một lệnh trong MIPS32 có độ dài 32 bits, còn trong MIPS64 là
64 bits. Lệnh được mô tả bằng hợp ngữ. Chúng ta có một danh sách các lệnh cho
kiến trúc MIPS, mỗi một lệnh sẽ được gán một mã nhị phân duy nhất. Một máy tính
sẽ có 2 lệnh cơ bản là cộng( add) và trừ( substract). Các giá trị của các phép
toán( source values) sẽ được lấy ra từ register file và sau khi tính toán thì kết quả sẽ
được lưu lại vào register file. Trong nội dung của báo cáo sẽ tập trung trình bày về
cấu trúc tập lệnh của MIPS32.
3.1. Nguyên tắc thiết kế tập lệnh MIPS
Tính đơn giản quan trọng hơn tính quy tắc:
- Chỉ thị lệnh có kích thước cố định: 32 bits với MIPS32 và 64 bits với
MIPS64.
- Ít định dạng chỉ thị lệnh: 3 loại định dạng.
- Mã lệnh ở vị trí cố định: 6 bit đầu.
Càng nhỏ thì xử lý càng nhanh:
- Số chỉ thị lệnh giới hạn.
- Số thanh ghi giới hạn.
Tăng tốc độ xử lý cho những trường hợp thường xuyên xảy ra:
- Các toán hạng số học lấy từ thanh ghi (dựa trên cơ chế load/store).
- Các chỉ thị lệnh có thể chứa toán hạng trực tiếp.
Thiết kế đòi hỏi sự thỏa hiệp tốt:
- 3 loại định dạng chỉ thị lệnh.
3.2. Các cấu trúc lệnh trong MIPS
3.2.1. Cấu trúc lệnh R-Format (Register)
- Cấu trúc lệnh:
- Các trường được sử dụng:
Trường Độ dài Ý nghĩa
opcode 6 bit Mã thao tác, cho biết lệnh làm gì
rd (Destination Register) 5 bit Thanh ghi đích, dùng để chứa kết quả của lệnh
rs (Source Register) 5 bit
Thanh ghi nguồn, dùng để chứa toán hạng
nguồn thứ nhất
rt (Target Register) 5 bit
Thanh ghi nguồn, dùng để chứa toán hạng
nguồn thứ hai
sa (shamt) 5 bit
Chứa số bit cần dịch trong các lệnh dịch, nếu
không có lệnh dịch thì trường này bằng 0
function 6 bit
Dùng kết hợp với opcode để cho biết lệnh làm
gì trong trường hợp các lệnh có cùng mã thao
tác opcode
Chú ý:
+ rs, rt, rd: đều có độ dài 5 bit, đủ để biểu diễn 32 thanh ghi của MIPS.
+ sa: có độ dài 5 bit, đủ để thực hiện dịch các bit trong một thanh ghi 32 bit
- Các lệnh sử dụng cấu trúc này: add, addu, sub, subu, add, or, nor, sll, srl, sra,…
3.2.2. Cấu trúc I-Format (Immediate)
- Cấu trúc lệnh:
- Các trường được sử dụng:
Trường Độ dài Ý nghĩa
opcode 6 bit
Mã thao tác, cho biết lệnh làm gì, tương tự
như R-Format, chỉ khác là không cần trường
funct
rs (Source Register) 5 bit
Thanh ghi nguồn, dùng để chứa toán hạng
nguồn thứ nhất
rt (Target Register) 5 bit
Thanh ghi đích, thường để chứa kết quả của
lệnh
immediate 16 bit
Có thể biểu diễn số nguyên từ -2
15
tới 2
15
-1, đủ
lớn để chứa giá trị độ dời từ địa chỉ thanh ghi
cơ sở ra rs nhằm phục vụ truy xuất bộ nhớ
trong lệnh lw và sw
- Các lệnh sử dụng cấu trúc này:
+ Sử dụng trong các trường hợp nạp/ghi dữ liệu và làm việc với hằng số. Một số
lệnh: lw, sw, lb, sb, lh, sh, addi, andi, ori, lui (sử dụng trong trường hợp thao tác với
hằng số 32 bit),…
+ Sử dụng trong trường hợp lệnh rẽ nhánh có điều kiện: beq, bne. Lúc này thì
trường immediate không chứa địa chỉ nhãn sẽ nhảy đến mà sẽ chứa khoảng cách so
với địa chỉ nằm trong thanh ghi PC (Program Counter) – thanh ghi chứa địa chỉ lệnh
đang được thực hiện. Tuy nhiên mỗi lệnh trong MIPS có kích thước 1 từ nhớ (32
bit) và MIPS truy xuất bộ nhớ theo nguyên tắc Alignment Restriction, do đó đơn vị
của immediate là từ nhớ. Cách tính địa chỉ rẽ nhánh có thể hiểu như sau:
Nếu không thực hiện rẽ nhánh: PC = PC + 4 (PC + 4: địa chỉ của lệnh kế tiếp trong
bộ nhớ)
Nếu thực hiện rẽ nhánh: PC = (PC + 4) + (immediate * 4)
Immediate: cho biết số lệnh cần nhảy qua để tới nhãn.
3.2.3. Cấu trúc J-Format (Jump)
- Cấu trúc lệnh:
- Các trường được sử dụng:
Trường Độ dài Ý nghĩa
opcode 6 bit Mã thao tác, cho biết lệnh làm gì
target address 26 bit Địa chỉ đích nhảy đến
- Các lệnh sử dụng cấu trúc này: cấu trúc lệnh J-Format được sử dụng chủ yếu
trong các lệnh nhảy: j, jr, jal,…
3.3. Các lệnh cơ bản trong kiến trúc MIPS
3.3.1. Các lệnh nạp/ghi (load/store)
- Đây là các lệnh duy nhất được phép truy xuất bộ nhớ trong tập lệnh của
MIPS. Các lệnh nạp và ghi (Load and Store Instructions) là các lệnh di chuyển dữ
liệu giữ bộ nhớ và các thanh ghi chung. Chúng đều là các lệnh có định dạng kiểu
immediate (I-type), do đó phương thức đánh địa chỉ duy nhất được hỗ trợ là thanh
ghi cơ sở cộng 16 bit, có bù định dạng immediate có dấu.
- Ví dụ:
Lw $t0, 12($s0): nạp từ nhớ có địa chỉ ($s0 + 12) và thanh ghi $t0
Sw $t0, 12($s0): lưu giá trị trong thanh ghi $t0 vào vùng nhớ có địa chỉ ($s0 +
12)
3.3.1.1. Các lệnh nạp (Load)
Câu lệnh Ví dụ Ý nghĩa
Lui (Load upper immediate) lui $s1,0xFD $s1=0xFD << 16
Li (Load immediate) li $s1,0xFD $s1=$s1 +0xFD
Liu (Load immediate un-signed) liu $s1,0xFD $s1=$s1 + 0xFD
La (Load address) la $s1,0xFD nạp địa chỉ của một nhãn
Lb (Load byte) lb $s1,0xFD nạp byte ở 0xFD vào $s1
Lh (Load halfword) lh $s1,0xFD Load halfword ở 0xFD vào $s1
Lw (Load word) lw $s1,0xFD Load word ở địa chỉ 0xFD vào
$s1
3.3.1.2. Các lệnh ghi (Store)
Câu lệnh Ví dụ Ý nghĩa
Cú pháp:
Opt opr, opr1 (opr2)
Opt – tên thao tác
Opr – Thanh ghi lưu trữ
Opr1 – Hằng số nguyên ( độ dời: luôn là bội số của 4 vì 1 từ nhớ được lưu trữ
chiếm 4 byte)
Opr2 – Thanh ghi địa chỉ vùng nhớ (thanh ghi cơ sở)
Sb (Store byte) sb $s1,0xFD
Lưu trữ byte thấp của thanh ghi
$s1 tới địa chỉ 0xFD
Sh (Store Halfword) sh $s1,0xFD
Lưu trữ halfword thấp của thanh
ghi tới địa chỉ 0xFD
Sw (Store word) sw $s1,0xFD
Lưu trữ word trong thanh ghi tới
địa chỉ 0xFD
Swl (Store word left) swl $s1,0xFD
Lưu trữ halfword cao trong
thanh ghi $s1 tới địa chỉ 0xFD
Swr (Store word right) swr $s1,0xFD
Lưu trữ halfword thấp trong
thanh ghi $s1 tới địa chỉ 0xFD
3.3.2. Các lệnh số học, logic và lệnh dịch
Các lệnh điện toán (Computational Instructions) thực hiện các phép tính số
học, logic, dịch chuyển, nhân, và chia trên các giá trị của các thanh ghi. Các lệnh
này bao gồm lệnh định dạng kiểu thanh ghi (kiểu R-type, trong đó đã bao gồm đồng
thời các toán hạng và kết quả được lưu trữ trong các thanh ghi) và định dạng kiểu
immediate (I-type, trong đó đã bao gồm một toán hạng có là một giá trị định dạng
immediate với 16 bit).
3.3.2.1. Lệnh số học
Cú pháp:
Opt opr, opr1,opr2
Opt – tên thao tác
Opr – Thanh ghi chứa kết quả
Opr1 – Thanh ghi (toán hạng nguồn thứ nhất)
Opr2 – Thanh ghi hoặc hằng số (toán hạng nguồn thứ hai)
- 8 thanh ghi thường được sử dụng để thực hiện các phép tính được đánh số từ $16
đến $23 ~ $s0 đến $s7
- 8 thanh ghi thường được sử dụng để lưu trữ tạm thời kết quả các phép toán được
đánh số từ $8 đến $15 ~ $t0 đến $t7
- Để thực hiện phép gán trong MIPS sẽ cho cộng giá trị cần gán với thanh ghi zero:
Add $s0,$s1,$0 hoặc add $s0,$s1,$zero
Câu lệnh Ví dụ Ý nghĩa
add add $s1,$s2,$s3 $s1=$s2+$s3
add w/o overflow addu $s1,$s2,$s3 $s1=$s2+$s3
add immediate addi $s1,$s2,10 $s1=$s2+10
add imm. w/o overflow addiu $s1,$s2,10 $s1=$s2+10
subtract sub $s1,$s2,$s3 $s1=$s2 - $s3
Subtract w/o overflow subu $s1,$s2,$s3 $s1=$s2 - $s3
Subtract immediate* subi $s1,$s2,10 $s1=$s2 – 10
Multiplication mult $s1,$s2
$hi=HIGH($s1
×
$s2)
$lo=LOW($s1
×
$s2)
Multiplication mul $s1,$s2,$s3
$s1=$s2
×
$s3
Multiplication w/o overflow multu $s1,$s2
$hi=HIGH($s1
×
$s2)
$lo=LOW($s1
×
$s2)
Division
Division unsigned
div $s1,$s2
divu $s1,$s2
$hi=$s1
÷
$s2
$hi=$s1 mod $s2
$hi=$s1
÷
$s2
$hi=$s1 mod $s2
3.3.3.2. Các lệnh logic
Cú pháp:
Opt opr, opr1,opr2
Opt – tên thao tác
Opr – Thanh ghi chứa kết quả (toán hạng đích)
Opr1 – Thanh ghi (toán hạng nguồn thứ nhất)
Opr2 – Thanh ghi hoặc hằng số (toán hạng nguồn thứ hai)
- Các lệnh and, or, nor: toán hạng nguồn thứ 2 phải là thanh ghi.
- Không tồn tại lệnh not mà sử dụng nor thay cho not: A nor 0 = not (A or 0) = not
A
- Phép and thường được sử dụng trong việc chuyển đổi ký tự thường thành ký tự
hoa, ký tự số thành số thông qua kỹ thuật mặt nạ.
Câu lệnh Ví dụ Ý nghĩa
AND and $s1,$s2,$s3 $s1=$s2 /\ $s3
AND immediate andi $s1,$s2,0xFD $s1=$s2 /\ 0xFD
NOR nor $s1,$s2,$s3 $s1= ¬($s2 \/ $s3 )
NOT* not $s1,$s2 $s1= ¬ $s2
OR or $s1,$s2,$s3 $s1=$s2 \/ $s3
OR immediate ori $s1,$s2,0xFD $s1=$s2 /\ 0xFD
Exclusive OR xor $s1,$s2,$s3
$s1=$s2
⊕
$s3
Exclusive OR imm xori $s1,$s2,0xFD
$s1=$s2
⊕
0xFD
Abs abs $s1,$s2 $s1= |$s2|
3.3.2.3. Các lệnh dịch
Cú pháp:
Opt opr, opr1,opr2
Opt – tên thao tác
Opr – Thanh ghi chứa kết quả
Opr1 – Thanh ghi (toán hạng nguồn thứ nhất)
Opr2 – Số bit dịch (hằng số < 32)
- Có thể sử dụng phép dịch trái để thực hiện phép nhân cho 2 mũ, và phép dịch phải
để thực hiện phép chia cho 2 mũ.
Câu lệnh Ví dụ Ý nghĩa
Shift left logical sll $s1,$s2,2 Dịch trái 2 bit, thêm vào các
bit 0 bên phải
Shift right logical srl $s1,$s2,2 Dịch phải 2 bit, thêm vào
các bit 0 bên trái
Shift right arithmetic sra $s1,$s2,2 Dịch phải số học 2 bit, thêm
vào 2 bit dấu (1) bên trái
- Ví dụ:
sll $s1, $s2, 2 # dịch trái luận lý $s2 2 bít
$s2 = 0000 0000 0000 0000 0000 0000 0101 0101 = 85
$s1 = 0000 0000 0000 0000 0000 0001 0101 0100 = 340
(85x2
2
)
srl $s1, $s2, 2 # dịch phải luận lý $s2 2 bít
$s2 = 0000 0000 0000 0000 0000 0000 0101 0101 = 8
$s1 = 0000 0000 0000 0000 0000 0000 0001 0101 = 21
(85/2
2
)
sra $s1, $s2, 2 # dịch phải số học $s2 2 bít
$s2 = 1111 1111 1111 1111 1111 1111 1111 0000 = -16
$s1 = 1111 1111 1111 1111 1111 1111 1100 0000 = -4
(-16/2
2
)
3.3.3. Các lệnh nhảy và rẽ nhánh
Các lệnh nhảy và rẽ nhánh (Jump and Branch Instructions) là các lệnh thay đổi
dòng kiểm soát của một chương trình. Lệnh rẽ nhánh có cấu trúc lệnh I-Format còn
lệnh nhảy sử dụng cấu trúc lệnh J-Format.
3.3.3.1. Các lệnh rẽ nhánh
Câu lệnh Ví dụ Ý nghĩa
b (Branch) b lab Rẽ nhánh vô điều kiện tới
nhãn lab.
beq (Branch on equal) beq $s1,$s2,L If ($s1 == $s2) go to L
bne (Branch on not equal) bne $s1,$s2,L If ($s1 != $s2) go to L
bgez (Branch on greater than
equal zero)
bgez $s1,L
If ($s1
≥
0) go toL
bgt (Branch on greater) bgt src1,src2,lab Branch if src1>src2
bgtz (Branch on greater than
Zero)
bgtz $s1,L If ($s1 > 0) go to L
blez (Branch on less than equal
zero)
blez $s1,L
If ($s1
≤
0) go to L
bltz (Branch on less than zero) bltz $s1,L If ($s1 < 0) go to L
bgezal (Branch on greater than
equal zero and link)
bgezal $s1,L
If ($s1
≥
0) $ra=PC + 4; go
to L
bltzal (Branch on less than zero
and link)
bltzal $s1,L If ($s1 < 0) $ra=PC + 4; go
to L
3.3.3.2. Các lệnh nhảy
- jal label: thực hiện 2 công việc
(1) Lưu địa chỉ của lệnh kế tiếp vào thanh ghi $ra
(2) Nhảy tới nhãn.
- jr register: nhảy tới địa chỉ nằm trong thanh ghi register
- 2 lệnh jal và jr được sử dụng hiệu quả trong thủ tục: lệnh jal lưu địa chỉ quay về
vào thanh ghi $ra và nhảy tới thủ tục. lệnh jr $ra nhảy về địa chỉ quay về được lưu
trong thanh ghi $ra.
Câu lệnh Ví dụ Ý nghĩa
j (Jump) j 0x2500 Go to addr 10,000
jal (Jump and link) jal 0x2500 $ra=PC +4; go to addr
10,000
jalr (Jump and link register) jalr $s1,$s2 $s2=PC + 4;go to $s1
jr (Jump register) jr $sr Go to $ra
3.3.4. Các lệnh di chuyển dữ liệu
Các câu lệnh di chuyển dữ liệu di chuyển dữ liệu giữa các thanh ghi. Các câu lệnh
đặc biệt được cung cấp để di chuyển dữ liệu vào và ra các thanh ghi đặc biệt là HI
và LO.
Câu lệnh Ví dụ Ý nghĩa
Move move $s1,$s2
Copy nội dung của $s2 tới
$s1
Mfhi mfhi $s1
Copy nội dung của thanh ghi
hi tới $s1
Mflo mflo $s1
Copy nội dung của thanh ghi
lo tới $s1
Mthi mthi $s2
Copy nội dung của $s2 tới
thanh ghi HI
Mtlo mtlo $s2
Copy nội dung của thanh ghi
$s2 tới thanh ghi LO
3.3.5. Làm việc với Stack
Stack (ngăn xếp) là vùng nhớ đặc biệt được truy cập theo cơ chế “vào trước ra sau”
(LIFO – Last In First Out), nghĩa là dữ liệu nào đưa vào sau sẽ được lấy ra trước.
Thanh ghi $sp đóng vai trò là con trỏ ngăn xếp (stack pointer), luôn chỉ đến đỉnh
của stack. Stack phát triển theo chiều giảm của địa chỉ vùng nhớ (đỉnh của stack
luôn có địa chỉ thấp). Hai thao tác cơ bản trong stack là push (đưa một phần tử vào
stack) và pop (lấy một phần tử ra khỏi stack). Cơ chế như sau:
• push: giảm $sp đi 4, lưu giá trị vào ô nhớ mà $sp chỉ đến.
Ví dụ: push vào stack giá trị trong $t0