Professional Documents
Culture Documents
Bao cao thuc hanh cuối kỳ
Bao cao thuc hanh cuối kỳ
MSSV : 22540020
Chương 1. IT002-Lab01
1. Lý thuyết Giảng viên hướng dẫn sinh viên sử dụng phần mềm Logisim dựa theo tài
liệu: Hướng dẫn sử dụng Logisim. Giảng viên giới thiệu cho sinh viên một số cổng luận
lý và thiết bị lưu trữ cơ bản trong phần mềm.
2. Thực hành
2.1. Tìm hiểu và mô phỏng các cổng luận lý sau: AND, OR, NOT, XOR, XNOR, NAND, NOR
2.2. Tìm hiểu và mô phỏng các thiết bị lưu trữ sau: D latch, D flip-flop, Thanh ghi (Register)
3. Bài tập
3.1. Mô phỏng các mạch tổ hợp sau:
3.2. Mô phỏng các mạch tuần tự sau:
Chương 2. IT002-Lab02
1. Lý thuyết Giảng viên giới thiệu về cấu trúc của một bộ xử lý, trong đó tập trung vào
ALU và Register Files. Giảng viên hướng dẫn sinh viên thiết kế mạch tổ hợp đơn giản
2. Thực hành
2.1.Mô phỏng ALU sau:
2.2.Mô phỏng Register Files sau:
3. Bài tập
3.1.Cải tiến ALU với các phép toán: A + B, A + 1, A – B, A – 1, A AND B, A OR B, A XOR
B, A XNOR B
3.3. Thiết kế và mô phỏng lại Register Files với địa chỉ xuất riêng với địa chỉ ghi?
3.4. Thiết kế mạch tổ hợp có chức năng chuyển đổi số thành MSSV như bảng bên
dưới?
Ví dụ: MSSV là 21522345
Chương 3. IT002-Lab03
1. Lý thuyết
Giảng viên hướng dẫn sinh viên sử dụng phần mềm MARS dựa theo tài liệu: MARS –
chương trình mô phỏng hợp ngữ (assembly) MIPS
2. Thực hành
2.1 Sinh viên tìm hiểu tài liệu “Một số lệnh assembly MIPS cơ bản” và mô phỏng việc thực
thi các lệnh và cho biết chức năng của các lệnh cơ bản sau: add, addi, addu, addiu,
sub, subu, and, andi, or, nor, lw, sw, slt, slti, sltu, sltiu, syscall
2.2 Mô phỏng các chương trình bên dưới và có biết ý nghĩa của chương trình:
3. Bài tập
2
3.1 Nhập vào một chuỗi, xuất ra cửa sổ I/O của MARS theo từng yêu cầu sau:
a) Khai báo và xuất ra cửa sổ I/O 2 chuỗi có giá trị như sau: 2 - Chuỗi 1: Chao ban! Ban la
sinh vien nam thu may? - Chuỗi 2: Hihi, minh la sinh vien nam thu 1 ^-^
b) Biểu diễn nhị phân của 2 chuỗi trên dưới bộ nhớ là gì?
c) Xuất ra lại đúng chuỗi đã nhập Ví dụ: Nhap: Truong Dai hoc Cong nghe Thong tin Xuất:
Truong Dai hoc Cong nghe Thong tin
d) Nhập vào 2 số nguyên sau đó xuất tổng của 2 số nguyên này
Chương 4. IT002-Lab04
1. Lý thuyết Giảng viên hướng dẫn sinh viên về chương trình hợp ngữ MIPS dựa theo tài liệu:
Tổng quát về hợp ngữ và kiến trúc MIPS
2. Thực hành
Chuyển đoạn code trong bảng theo sau sang MIPS và sử dụng MARS để kiểm tra lại kết quả:
if (i == j)
f = g + h;
else
f = g – h;
(Với giá trị của i, j, f, g, h lần lượt chứa trong các thanh ghi $s0, $s1, $s2, $t0, $t1)
int Sum = 0
for (int i = 1; i <=N; ++i)
{ Sum = Sum + i; }
(Với giá trị của i, N, Sum lần lượt chứa trong các thanh ghi $s0, $s1, $s2)
3. Bài tập
a. Nhập vào một ký tự, xuất ra cửa sổ I/O của MARS theo từng yêu cầu sau:
✓ Ký tự liền trước và liền sau của ký tự nhập vào
Ví dụ: Nhap ky tu (chỉ một ký tự): b
Ky tu truoc: a
Ky tu sau: c
✓ Ký tự nhập vào chỉ được phép là ba loại: số, chữ thường và chữ hoa. Nếu ký tự nhập vào
rơi vào một trong ba loại, xuất ra cửa sổ đó là loại nào; nếu ký tự nhập không rơi vào một
trong ba loại trên, xuất ra thông báo “invalid type”
b. Nhập từ bàn phím 2 số nguyên, in ra cửa sổ I/O của MARS theo từng yêu cầu sau:
✓ Số lớn hơn
✓ Tổng, hiệu, tích và thương của hai số
Chương 5. IT002-Lab05
1. Thao tác với mảng Mảng với n phần tử là một chuỗi n phần tử liên tiếp nhau trong bộ
nhớ. Thao tác với mảng trong MIPS là thao tác trực tiếp với byte/word trong bộ nhớ.
▪ Để cấp phát chuỗi word hoặc byte trong bộ nhớ, có giá trị khởi tao sử dụng “.word”
hoặc “.byte” trong “.data”
▪ Để cấp phát chuỗi byte không có giá trị khởi tạo trước, sử dụng “.space” trong “.data”
3
Cho ba mảng với cấp phát dữ liệu trong bộ nhớ như sau:
.data
array1: .word 5, 6, 7, 8, 1, 2, 3, 9, 10, 4
size1: .word 10
array3: .space 8
size3: .word 8
Mảng array1 có 10 word, kích thước được lưu trong size1; Mảng array2 có 16 byte,
kích thước được lưu trong size2; Mảng array3 có 8 byte, kích thước được lưu trong
size3.
Viết code trong phần “.text” thực hiện riêng từng phần việc:
✓ In ra cửa sổ I/O của MARS tất cả các phần tử của mảng array1 và array2
✓ Gán các giá trị cho mảng array3 sao cho array3[i] = array2[i] + array2[size2 - 1 - i]
✓ Người sử dụng nhập vào mảng thứ mấy và chỉ số phần tử cần lấy trong mảng đó,
chương trình xuất ra phần tử tương ứng.
4
Chương 1. IT002-Lab01
1. Lý thuyết Giảng viên hướng dẫn sinh viên sử dụng phần mềm Logisim dựa theo tài
liệu: Hướng dẫn sử dụng Logisim. Giảng viên giới thiệu cho sinh viên một số cổng luận
lý và thiết bị lưu trữ cơ bản trong phần mềm.
2. Thực hành
2.1. Tìm hiểu và mô phỏng các cổng luận lý sau: AND, OR, NOT, XOR, XNOR, NAND,
NOR
Các cổng luận lý là các phép toán cơ bản trong lý thuyết mạch điện tử và lập trình máy tính. Chúng được
sử dụng để thực hiện các phép toán luận lý trên các tín hiệu điện tử hoặc dữ liệu nhị phân. Dưới đây là mô
tả ngắn gọn về các cổng luận lý bạn đề cập:
AND: Cổng AND chỉ trả về giá trị 1 khi tất cả các đầu vào đều có giá trị 1, nếu không thì nó trả về
giá trị 0.
OR: Cổng OR chỉ trả về giá trị 1 khi ít nhất một trong các đầu vào có giá trị 1, nếu không thì nó trả
về giá trị 0.
5
NOT: Cổng NOT đảo ngược giá trị đầu vào, nghĩa là nếu đầu vào là 1 thì nó trả về 0 và ngược lại.
XOR: Cổng XOR (Exclusive OR) chỉ trả về giá trị 1 khi số lượng các đầu vào có giá trị 1 là lẻ, nếu
không thì nó trả về giá trị 0.
6
XNOR: Cổng XNOR (Exclusive NOR) chỉ trả về giá trị 1 khi số lượng các đầu vào có giá trị 1 là
chẵn, nếu không thì nó trả về giá trị 0.
NAND: Cổng NAND (NOT AND) là sự kết hợp của cổng AND và NOT. Nó chỉ trả về giá trị 0 khi tất
cả các đầu vào đều có giá trị 1, nếu không thì nó trả về giá trị 1.
7
NOR: Cổng NOR (NOT OR) là sự kết hợp của cổng OR và NOT. Nó chỉ trả về giá trị 0 khi ít nhất
một trong các đầu vào có giá trị 1, nếu không thì nó trả về giá trị 1.
2.2. Tìm hiểu và mô phỏng các thiết bị lưu trữ sau: D latch, D flip-flop, Thanh ghi (Register)
8
D latch: D latch (Data latch) là một thiết bị lưu trữ dữ liệu 1 bit. Nó có hai đầu vào là D (Data) và E
(Enable). Khi E có giá trị 1, giá trị tại đầu ra Q của D latch sẽ bằng với giá trị tại đầu vào D. Khi E có giá trị
0, giá trị tại đầu ra Q sẽ được giữ nguyên, không thay đổi cho dù giá trị tại đầu vào D có thay đổi.
D flip-flop: D flip-flop (Data flip-flop) cũng là một thiết bị lưu trữ dữ liệu 1 bit. Nó có hai đầu vào là D
(Data) và CLK (Clock). Giá trị tại đầu ra Q của D flip-flop sẽ được cập nhật với giá trị tại đầu vào D mỗi khi
có sự thay đổi từ mức thấp sang mức cao tại đầu vào CLK.
Register: Register (Thanh ghi) là một thiết bị lưu trữ nhiều bit dữ liệu. Nó được cấu thành từ nhiều
flip-flop hoặc latch được kết nối với nhau để lưu trữ một từ dữ liệu có nhiều bit. Register thường được sử
dụng trong CPU để lưu trữ các dữ liệu và lệnh được sử dụng thường xuyên.
3. Bài tập
3.1. Mô phỏng các mạch tổ hợp sau:
9
3.2. Mô phỏng các mạch tuần tự sau:
Chương 2. IT002-Lab02
10
4. Lý thuyết Giảng viên giới thiệu về cấu trúc của một bộ xử lý, trong đó tập trung vào
ALU và Register Files. Giảng viên hướng dẫn sinh viên thiết kế mạch tổ hợp đơn giản
5. Thực hành
5.1.Mô phỏng ALU sau:
5.2.Mô phỏng Register Files sau:
6. Bài tập
6.1.Cải tiến ALU với các phép toán: A + B, A + 1, A – B, A – 1, A AND B, A OR B, A XOR
B, A XNOR B
3.5. Thiết kế và mô phỏng lại Register Files với địa chỉ xuất riêng với địa chỉ ghi?
3.6. Thiết kế mạch tổ hợp có chức năng chuyển đổi số thành MSSV như bảng bên
dưới?
Ví dụ: MSSV là 21522345
Chương 3. IT002-Lab03
11
1. Lý thuyết
Giảng viên hướng dẫn sinh viên sử dụng phần mềm MARS dựa theo tài liệu: MARS –
chương trình mô phỏng hợp ngữ (assembly) MIPS
2. Thực hành
2.1 Sinh viên tìm hiểu tài liệu “Một số lệnh assembly MIPS cơ bản” và mô phỏng việc thực
thi các lệnh và cho biết chức năng của các lệnh cơ bản sau: add, addi, addu, addiu,
sub, subu, and, andi, or, nor, lw, sw, slt, slti, sltu, sltiu, syscall
add: Lệnh này dùng để cộng hai thanh ghi số nguyên và lưu kết quả vào một thanh ghi khác. Ví dụ:
add $t0, $s0, $s1 có nghĩa là cộng nội dung của thanh ghi $s0 và $s1 và lưu kết quả vào thanh ghi
$t0. Lệnh này sẽ sinh ra ngoại lệ nếu có tràn số.
addi: Lệnh này dùng để cộng một thanh ghi số nguyên với một hằng số và lưu kết quả vào một
thanh ghi khác. Ví dụ: addi $t0, $s0, 10 có nghĩa là cộng nội dung của thanh ghi $s0 với 10 và lưu
kết quả vào thanh ghi $t0. Lệnh này sẽ sinh ra ngoại lệ nếu có tràn số.
addu: Lệnh này giống như lệnh add nhưng không sinh ra ngoại lệ nếu có tràn số. Thay vào đó, nó sẽ
bỏ qua bit tràn và tiếp tục thực hiện phép cộng.
addiu: Lệnh này giống như lệnh addi nhưng không sinh ra ngoại lệ nếu có tràn số. Thay vào đó, nó
sẽ bỏ qua bit tràn và tiếp tục thực hiện phép cộng.
sub: Lệnh này dùng để trừ hai thanh ghi số nguyên và lưu kết quả vào một thanh ghi khác. Ví dụ:
sub $t0, $s0, $s1 có nghĩa là trừ nội dung của thanh ghi $s1 từ $s0 và lưu kết quả vào thanh ghi $t0.
Lệnh này sẽ sinh ra ngoại lệ nếu có tràn số.
subu: Lệnh này giống như lệnh sub nhưng không sinh ra ngoại lệ nếu có tràn số. Thay vào đó, nó sẽ
bỏ qua bit tràn và tiếp tục thực hiện phép trừ.
and: Lệnh này dùng để thực hiện phép toán luận lý AND giữa hai thanh ghi số nguyên và lưu kết
quả vào một thanh ghi khác. Ví dụ: and $t0, $s0, $s1 có nghĩa là tính toán kết quả của phép toán
AND giữa từng cặp bit tương ứng của hai thanh ghi $s0 và $s1 và lưu kết quả vào thanh ghi $t0.
andi: Lệnh này dùng để thực hiện phép toán luận lý AND giữa một thanh ghi số nguyên và một
hằng số và lưu kết quả vào một thanh ghi khác. Ví dụ: andi $t0, $s0, 15 có nghĩa là tính toán kết quả
của phép toán AND giữa nội dung của thanh ghi $s0 và hằng số 15 và lưu kết quả vào thanh ghi
$t0.
or: Lệnh này dùng để thực hiện phép toán luận lý OR giữa hai thanh ghi số nguyên và lưu kết quả
vào một thanh ghi khác. Ví dụ: or $t0, $s0, $s1 có nghĩa là tính toán kết quả của phép toán OR giữa
từng cặp bit tương ứng của hai thanh ghi $s0 và $s1 và lưu kết quả vào thanh ghi $t0.
nor: Lệnh này dùng để thực hiện phép toán luận lý NOR giữa hai thanh ghi số nguyên và lưu kết
quả vào một thanh ghi khác. Ví dụ: nor $t0, $s0, $s1 có nghĩa là tính toán kết quả của phép toán
NOR giữa từng cặp bit tương ứng của hai thanh ghi $s0 và $s1 và lưu kết quả vào thanh ghi $t0.
12
lw: Lệnh này dùng để đọc một từ (32 bit) dữ liệu từ bộ nhớ và lưu vào một thanh ghi. Ví dụ: lw $t0,
4($s0) có nghĩa là đọc một từ dữ liệu từ địa chỉ bộ nhớ bằng với nội dung của thanh ghi $s0 cộng
với 4 và lưu vào thanh ghi $t0.
sw: Lệnh này dùng để ghi một từ (32 bit) dữ liệu từ một thanh ghi vào bộ nhớ. Ví dụ: sw $t0, 4($s0)
có nghĩa là ghi một từ dữ liệu từ nội dung của thanh ghi $t0 vào địa chỉ bộ nhớ bằng với nội dung
của thanh ghi $s0 cộng với 4.
slt: Lệnh này dùng để so sánh hai thanh ghi số nguyên có dấu và đặt giá trị 1 vào một thanh ghi
khác nếu điều kiện thỏa mãn, ngược lại đặt giá trị 0. Ví dụ: slt $t0, $s0, $s1 có nghĩa là so sánh nội
dung của hai thanh ghi $s0 và $s1 theo điều kiện ($s0 < $s1) và đặt giá trị 1 vào thanh ghi $t0 nếu
điều kiện đúng, ngược lại đặt giá trị 0.
slti: Lệnh này dùng để so sánh một thanh ghi số nguyên có dấu với một hằng số và đặt giá trị 1 vào
một thanh ghi khác nếu điều kiện thỏa mãn, ngược lại đặt giá trị 0. Ví dụ: slti $t0, $s0, 10 có nghĩa là
so sánh nội dung của thanh ghi $s0 với hằng số 10 theo điều kiện ($s0 < 10) và đặt giá trị 1 vào
thanh ghi $t0 nếu điều kiện đúng, ngược lại đặt giá trị 0.
sltu: lệnh so sánh nhỏ hơn không dấu (set on less than unsigned). Lệnh này sẽ gán giá trị 1 cho
thanh ghi đích nếu thanh ghi nguồn 1 nhỏ hơn thanh ghi nguồn 2 theo kiểu số không dấu, ngược
lại gán giá trị 01.
sltiu: lệnh so sánh nhỏ hơn không dấu với số tức thời (set on less than immediate unsigned). Lệnh
này sẽ gán giá trị 1 cho thanh ghi đích nếu thanh ghi nguồn nhỏ hơn số tức thời theo kiểu số không
dấu, ngược lại gán giá trị 01.
syscall: lệnh gọi hệ thống (system call). Lệnh này sẽ yêu cầu hệ điều hành thực hiện một chức năng
nào đó được xác định bởi giá trị của thanh ghi $v0
2.2 Mô phỏng các chương trình bên dưới và có biết ý nghĩa của chương trình:
3. Bài tập
3.1 Nhập vào một chuỗi, xuất ra cửa sổ I/O của MARS theo từng yêu cầu sau:
a) Khai báo và xuất ra cửa sổ I/O 2 chuỗi có giá trị như sau: 2 - Chuỗi 1: Chao ban! Ban la
sinh vien nam thu may? - Chuỗi 2: Hihi, minh la sinh vien nam thu 1 ^-^
13
b) Biểu diễn nhị phân của 2 chuỗi trên dưới bộ nhớ là gì?
c) Xuất ra lại đúng chuỗi đã nhập Ví dụ: Nhap: Truong Dai hoc Cong nghe Thong tin Xuất:
Truong Dai hoc Cong nghe Thong tin
d) Nhập vào 2 số nguyên sau đó xuất tổng của 2 số nguyên này
.data
string1: .asciiz "Chao ban! Ban la sinh vien nam thu may?"
string2: .asciiz "Hihi, minh la sinh vien nam thu 1 ^-^"
input: .space 256
prompt: .asciiz "Nhap: "
result: .asciiz "Xuat: "
num1_prompt: .asciiz "Nhap so nguyen thu nhat: "
num2_prompt: .asciiz "Nhap so nguyen thu hai: "
sum_result: .asciiz "Tong cua 2 so nguyen la: "
.text
main:
# a) Khai báo và xuất ra cửa sổ I/O 2 chuỗi có giá trị như sau:
# 2 - Chuỗi 1: Chao ban! Ban la sinh vien nam thu may?
# - Chuỗi 2: Hihi, minh la sinh vien nam thu 1 ^-^
li $v0, 4
la $a0, string1
syscall
li $v0, 4
la $a0, string2
syscall
# b) Biểu diễn nhị phân của 2 chuỗi trên dưới bộ nhớ là gì?
# Để xem biểu diễn nhị phân của các chuỗi trong bộ nhớ, bạn có thể sử dụng chế độ xem bộ nhớ
(Memory) trong MARS và nhập địa chỉ của các chuỗi.
14
syscall
li $v0, 5
syscall
move $t0, $v0
li $v0, 4
la $a0, num2_prompt
syscall
li $v0, 5
syscall
li $v0, 4
la $a0, sum_result
syscall
li $v0, 1
move $a0, $t1
syscall
exit:
li $v0,10
syscall
Chương 4. IT002-Lab04
1. Lý thuyết Giảng viên hướng dẫn sinh viên về chương trình hợp ngữ MIPS dựa theo tài liệu:
Tổng quát về hợp ngữ và kiến trúc MIPS
2. Thực hành
Chuyển đoạn code trong bảng theo sau sang MIPS và sử dụng MARS để kiểm tra lại kết quả:
if (i == j)
f = g + h;
else
f = g – h;
(Với giá trị của i, j, f, g, h lần lượt chứa trong các thanh ghi $s0, $s1, $s2, $t0, $t1)
int Sum = 0
for (int i = 1; i <=N; ++i)
{ Sum = Sum + i; }
(Với giá trị của i, N, Sum lần lượt chứa trong các thanh ghi $s0, $s1, $s2)
# if (i == j) f = g + h; else f = g - h;
# (Với giá trị của i, j, f, g, h lần lượt chứa trong các thanh ghi $s0, $s1, $s2, $t0, $t1)
15
end:
3. Bài tập
a. Nhập vào một ký tự, xuất ra cửa sổ I/O của MARS theo từng yêu cầu sau:
✓ Ký tự liền trước và liền sau của ký tự nhập vào
Ví dụ: Nhap ky tu (chỉ một ký tự): b
Ky tu truoc: a
Ky tu sau: c
✓ Ký tự nhập vào chỉ được phép là ba loại: số, chữ thường và chữ hoa. Nếu ký tự nhập vào
rơi vào một trong ba loại, xuất ra cửa sổ đó là loại nào; nếu ký tự nhập không rơi vào một
trong ba loại trên, xuất ra thông báo “invalid type”
b. Nhập từ bàn phím 2 số nguyên, in ra cửa sổ I/O của MARS theo từng yêu cầu sau:
✓ Số lớn hơn
✓ Tổng, hiệu, tích và thương của hai số
Câu a:
.data
prompt: .asciiz "Nhap ky tu (chỉ một ký tự): "
before: .asciiz "\nKy tu truoc: "
after: .asciiz "\nKy tu sau: "
invalid: .asciiz "\ninvalid type"
.text
li $v0, 4
la $a0, prompt
syscall # in ra dòng nhắc nhập ký tự
li $v0, 12
syscall # đọc ký tự từ bàn phím
move $t0, $v0 # lưu ký tự vào thanh ghi $t0
li $v0, 4
la $a0, before
syscall # in ra dòng "Ky tu truoc: "
16
li $v0, 4
la $a0, after
syscall # in ra dòng "Ky tu sau: "
# Kiểm tra ký tự nhập vào có phải là số, chữ thường hoặc chữ hoa không
li $t1, '0'
li $t2, '9'
li $t3, 'a'
li $t4, 'z'
li $t5, 'A'
li $t6, 'Z'
blt $t0, $t1, invalid_type # nếu ký tự < '0' thì invalid type
bgt $t0, $t2, not_digit # nếu ký tự > '9' thì không phải là số
# Nếu ký tự nằm trong khoảng ['0', '9'] thì xuất ra thông báo là số
li $v0, 4
la $a0, digit_msg
syscall
j end
not_digit:
blt $t0, $t3, invalid_type # nếu ký tự < 'a' thì invalid type
bgt $t0, $t4, not_lowercase # nếu ký tự > 'z' thì không phải là chữ thường
# Nếu ký tự nằm trong khoảng ['a', 'z'] thì xuất ra thông báo là chữ thường
li $v0, 4
la $a0, lowercase_msg
syscall
j end
not_lowercase:
blt $t0, $t5, invalid_type # nếu ký tự < 'A' thì invalid type
bgt $t0, $t6, invalid_type # nếu ký tự > 'Z' thì invalid type
# Nếu ký tự nằm trong khoảng ['A', 'Z'] thì xuất ra thông báo là chữ hoa
li $v0, 4
la $a0, uppercase_msg
syscall
j end
invalid_type:
# Nếu ký tự không thuộc ba loại trên thì xuất ra thông báo invalid type
li $v0, 4
la $a0, invalid_msg
syscall
end:
17
Câu b:
.data
prompt: .asciiz "Nhap ky tu (chỉ một ký tự): "
before: .asciiz "\nKy tu truoc: "
after: .asciiz "\nKy tu sau: "
invalid: .asciiz "\ninvalid type"
.text
li $v0, 4
la $a0, prompt
syscall # in ra dòng nhắc nhập ký tự
li $v0, 12
syscall # đọc ký tự từ bàn phím
move $t0, $v0 # lưu ký tự vào thanh ghi $t0
li $v0, 4
la $a0, before
syscall # in ra dòng "Ky tu truoc: "
li $v0, 4
la $a0, after
syscall # in ra dòng "Ky tu sau: "
# Kiểm tra ký tự nhập vào có phải là số, chữ thường hoặc chữ hoa không
li $t1, '0'
li $t2, '9'
li $t3, 'a'
li $t4, 'z'
li $t5, 'A'
li $t6, 'Z'
blt $t0, $t1, invalid_type # nếu ký tự < '0' thì invalid type
bgt $t0, $t2, not_digit # nếu ký tự > '9' thì không phải là số
# Nếu ký tự nằm trong khoảng ['0', '9'] thì xuất ra thông báo là số
li $v0, 4
la $a0, digit_msg
syscall
j end
not_digit:
blt $t0, $t3, invalid_type # nếu ký tự < 'a' thì invalid type
bgt $t0, $t4, not_lowercase # nếu ký tự > 'z' thì không phải là chữ thường
18
# Nếu ký tự nằm trong khoảng ['a', 'z'] thì xuất ra thông báo là chữ thường
li $v0, 4
la $a0, lowercase_msg
syscall
j end
not_lowercase:
blt $t0, $t5, invalid_type # nếu ký tự < 'A' thì invalid type
bgt $t0, $t6, invalid_type # nếu ký tự > 'Z' thì invalid type
# Nếu ký tự nằm trong khoảng ['A', 'Z'] thì xuất ra thông báo là chữ hoa
li $v0, 4
la $a0, uppercase_msg
syscall
j end
invalid_type:
# Nếu ký tự không thuộc ba loại trên thì xuất ra thông báo invalid type
li $v0, 4
la $a0, invalid_msg
syscall
end:
Chương 5. IT002-Lab05
4. Thao tác với mảng Mảng với n phần tử là một chuỗi n phần tử liên tiếp nhau trong bộ
nhớ. Thao tác với mảng trong MIPS là thao tác trực tiếp với byte/word trong bộ nhớ.
▪ Để cấp phát chuỗi word hoặc byte trong bộ nhớ, có giá trị khởi tao sử dụng “.word”
hoặc “.byte” trong “.data”
▪ Để cấp phát chuỗi byte không có giá trị khởi tạo trước, sử dụng “.space” trong “.data”
Cho ba mảng với cấp phát dữ liệu trong bộ nhớ như sau:
.data
array1: .word 5, 6, 7, 8, 1, 2, 3, 9, 10, 4
size1: .word 10
array3: .space 8
size3: .word 8
Mảng array1 có 10 word, kích thước được lưu trong size1; Mảng array2 có 16 byte,
kích thước được lưu trong size2; Mảng array3 có 8 byte, kích thước được lưu trong
size3.
Viết code trong phần “.text” thực hiện riêng từng phần việc:
✓ In ra cửa sổ I/O của MARS tất cả các phần tử của mảng array1 và array2
19
✓ Gán các giá trị cho mảng array3 sao cho array3[i] = array2[i] + array2[size2 - 1 - i]
✓ Người sử dụng nhập vào mảng thứ mấy và chỉ số phần tử cần lấy trong mảng đó,
chương trình xuất ra phần tử tương ứng.
.data
array1: .word 5, 6, 7, 8, 1, 2, 3, 9, 10, 4
size1: .word 10
array3: .space 8
size3: .word 8
.text
# In ra cửa sổ I/O của MARS tất cả các phần tử của mảng array1 và array2
li $t0, 1 # biến đếm cho mảng thứ nhất
li $t1, 0 # biến đếm cho phần tử trong mảng thứ nhất
la $t2, array1 # địa chỉ của mảng thứ nhất
lw $t3, size1 # kích thước của mảng thứ nhất
print_loop:
beq $t0, $t4, print_array2 # nếu đang in mảng thứ hai thì nhảy đến nhãn print_array2
beq $t1, $t3, next_array # nếu đã in hết phần tử của mảng thứ nhất thì nhảy đến nhãn
next_array
li $v0, 1
move $a0, $t0
syscall
# In ra dòng "Phan tu thu y" với y là số thứ tự của phần tử trong mảng
li $v0, 4
la $a0, element_msg
syscall
20
li $v0, 1
syscall
# In ra giá trị của phần tử tại vị trí hiện tại trong mảng thứ nhất (word)
lw $a0, ($t2)
li $v0 ,1
syscall
# Tăng biến đếm cho phần tử lên một đơn vị và tăng địa chỉ lên bốn byte (word)
addi $t1 , $t1 ,1
addi $t2 , $t2 ,4
next_array:
# Chuyển sang in mảng thứ hai và reset biến đếm cho phần tử về không
move $t0 , $t4
li $t1 ,0
print_array2:
beq $t5 , $t7 , end_print # nếu đã in hết phần tử của mảng thứ hai thì nhảy đến nhãn end_print
li $v0 ,1
move $a0 ,$t0
syscall
# In ra dòng "Phan tu thu y" với y là số thứ tự của phần tử trong mảng
li $v0 ,4
la $a0 ,element_msg
syscall
# In ra giá trị của phần tử tại vị trí hiện tại trong mảng thứ hai (byte)
lb $a0 ,($t6)
li $v0 ,1
syscall
# Tăng biến đếm cho phần tử lên một đơn vị và tăng địa chỉ lên một byte (byte)
addi $t5 ,$t5 ,1
addi $t6 ,$t6 ,1
21
end_print:
# Gán các giá trị cho mảng array3 sao cho array3[i] = array2[i] + array2[size2 - 1 - i]
li $t0, 0 # biến đếm cho phần tử trong mảng
la $t1, array2 # địa chỉ của mảng array2
la $t2, array3 # địa chỉ của mảng array3
lw $t3, size2 # kích thước của mảng array2
assign_loop:
beq $t0, $t3, end_assign # nếu đã gán hết phần tử thì nhảy đến nhãn end_assign
# Lấy giá trị của array2[i] và lưu vào thanh ghi $t4
lb $t4, ($t1)
# Tính chỉ số của phần tử đối xứng với i trong mảng array2 và lưu vào thanh ghi $t5
subi $t5, $t3, 1
sub $t5, $t5, $t0
# Lấy giá trị của array2[size2 - 1 - i] và lưu vào thanh ghi $t6
sll $t6, $t5, 0 # nhân với 1 để chuyển từ chỉ số sang độ dời byte
add $t6, $t6, $t1 # cộng với địa chỉ ban đầu của mảng để ra địa chỉ của phần tử cần lấy
lb $t6, ($t6)
# Cộng hai giá trị lại và lưu vào thanh ghi $t7
addu $t7, $t4, $t6
# Tăng biến đếm cho phần tử lên một đơn vị và tăng địa chỉ lên một byte (byte) cho cả hai
mảng
addi $t0, $t0, 1
addi $t1, $t1, 1
addi $t2, $t2, 1
end_assign:
# Người sử dụng nhập vào mảng thứ mấy và chỉ số phần tử cần lấy trong mảng đó, chương
trình xuất ra phần tử tương ứng.
li $v0 ,4
la $a0 ,input_msg
syscall # in ra dòng nhắc nhập
li $v0 ,5
syscall # đọc số nguyên từ bàn phím là số thứ tự của mảng cần lấy
move $s0 ,$v0 # lưu số thứ tự của mảng vào thanh ghi $s0
li $v0 ,5
syscall # đọc số nguyên từ bàn phím là chỉ số của phần tử cần lấy
move $s1 ,$v0 # lưu chỉ số của phần tử vào thanh ghi $s1
22
beqz $s0 ,error_input # nếu số thứ tự của mảng bằng không thì nhảy đến nhãn error_input
bgt $s0 ,3 ,error_input # nếu số thứ tự của mảng lớn hơn ba thì nhảy đến nhãn error_input
bltz $s1 ,error_input # nếu chỉ số của phần tử nhỏ hơn không thì nhảy đến nhãn error_input
beq $s0 ,1 ,get_array1 # nếu số thứ tự của mảng bằng một thì nhảy đến nhãn get_array1
beq $s0 ,2 ,get_array2 # nếu số thứ tự của mảng bằng hai thì nhảy đến nhãn get_array2
beq $s0 ,3 ,get_array3 # nếu số thứ tự của mảng bằng ba thì nhảy đến nhãn get_array3
get_array1:
lw $t0 ,size1 # lấy kích thước của mảng array1
bgt $s1 ,$t0 ,error_input # nếu chỉ số của phần tử lớn hơn kích thước của mảng thì nhảy đến
nhãn error_input
get_array2:
lw $t0 ,size2 # lấy kích thước của mảng array2
bgt $s1 ,$t0 ,error_input # nếu chỉ số của phần tử lớn hơn kích thước của mảng thì nhảy đến
nhãn error_input
get_array3:
lw $t0 ,size3 # lấy kích thước của mảng array3
bgt $s1 ,$t0 ,error_input # nếu chỉ số của phần tử lớn hơn kích thước của mảng thì nhảy đến
nhãn error_input
print_element:
li $v0 ,1
syscall # in ra giá trị của phần tử
error_input:
li $v0 ,4
la $a0 ,error_msg
syscall # in ra dòng thông báo lỗi nhập liệu
23
end_program:
.data
a: .word 5
b: .word 6
c: .word 7
d: .word 8
.text
# Thực hiện lại các yêu cầu của nội dung 1 với con trỏ
# a. Tính tổng của hai số được lưu trong hai con trỏ ptr1 và ptr2, lưu kết quả vào thanh ghi $s0
lw $t0, ptr1 # lấy địa chỉ của biến a từ con trỏ ptr1
lw $t1, ($t0) # lấy giá trị của biến a từ địa chỉ đã lấy
lw $t2, ptr2 # lấy địa chỉ của biến b từ con trỏ ptr2
lw $t3, ($t2) # lấy giá trị của biến b từ địa chỉ đã lấy
add $s0, $t1, $t3 # cộng hai giá trị lại và lưu vào thanh ghi $s0
# b. Tính hiệu của hai số được lưu trong hai con trỏ ptr3 và ptr4, lưu kết quả vào thanh ghi $s1
lw $t0, ptr3 # lấy địa chỉ của biến c từ con trỏ ptr3
lw $t1, ($t0) # lấy giá trị của biến c từ địa chỉ đã lấy
lw $t2, ptr4 # lấy địa chỉ của biến d từ con trỏ ptr4
lw $t3, ($t2) # lấy giá trị của biến d từ địa chỉ đã lấy
sub $s1, $t1, $t3 # trừ hai giá trị lại và lưu vào thanh ghi $s1
# c. Tính tích của hai số được lưu trong thanh ghi $s0 và $s1, lưu kết quả vào thanh ghi $s2
mul $s2, $s0, $s1 # nhân hai giá trị lại và lưu vào thanh ghi $s2
# d. Tính thương của hai số được lưu trong thanh ghi $s0 và $s1, lưu kết quả vào thanh ghi $s3 (phần
nguyên) và thanh ghi $s4 (phần dư)
div $s3, $s4, $s0, $s1 # chia hai giá trị lại và lưu phần nguyên vào thanh ghi $s3 và phần dư vào thanh
ghi $s4
# e. In ra màn hình các kết quả được lưu trong các thanh ghi từ $s0 đến $s4 theo thứ tự tăng dần của
chỉ số thanh ghi
li $v0 ,4
la $a0 ,sum_msg
syscall # in ra dòng "Tong la: "
li $v0 ,4
la $a0 ,diff_msg
syscall # in ra dòng "Hieu la: "
24
move $a0 ,$s1
li $v0 ,1
syscall # in ra giá trị của hiệu
li $v0 ,4
la $a0 ,product_msg
syscall # in ra dòng "Tich la: "
li $v0 ,4
la $a0 ,quotient_msg
syscall # in ra dòng "Thuong la: "
li $v0 ,4
la $a0 ,remainder_msg
syscall # in ra dòng "Du la: "
.data
input_size: .asciiz "Nhap so phan tu cua mang: "
input_element: .asciiz "Nhap phan tu thu "
input_index: .asciiz "\nNhap chi so cua phan tu can lay: "
max_msg: .asciiz "\nGia tri lon nhat cua mang la: "
min_msg: .asciiz "\nGia tri nho nhat cua mang la: "
sum_msg: .asciiz "\nTong cac phan tu cua mang la: "
element_msg: .asciiz "\nGia tri cua phan tu can lay la: "
.text
# Nhập một mảng các số nguyên n phần tử (nhập vào số phần tử và giá trị của từng phần tử)
li $v0, 4
la $a0, input_size
syscall # in ra dòng nhắc nhập số phần tử
li $v0, 5
syscall # đọc số nguyên từ bàn phím là số phần tử của mảng
move $s0, $v0 # lưu số phần tử vào thanh ghi $s0
25
li $t0, 0 # biến đếm cho phần tử trong mảng
li $t1, 4 # kích thước của một word (byte)
mul $t2, $s0, $t1 # tính kích thước cần cấp phát cho mảng (byte)
li $v0, 9
move $a0, $t2
syscall # cấp phát bộ nhớ cho mảng
move $s1, $v0 # lưu địa chỉ của mảng vào thanh ghi $s1
input_loop:
beq $t0, $s0, end_input # nếu đã nhập đủ số phần tử thì nhảy đến nhãn end_input
li $v0, 4
la $a0, input_element
syscall # in ra dòng nhắc nhập phần tử
li $v0, 5
syscall # đọc số nguyên từ bàn phím là giá trị của phần tử
sw $v0, ($s1) # lưu giá trị của phần tử vào mảng
# Tăng biến đếm cho phần tử lên một đơn vị và tăng địa chỉ lên bốn byte (word)
addi $t0, $t0, 1
addi $s1, $s1, 4
end_input:
# Xuất ra giá trị lớn nhất và nhỏ nhất của mảng
subi $s1, $s1, 4 # trừ đi bốn byte để trỏ về phần tử cuối cùng của mảng
lw $t3 ,($s1)
move $t4 ,$t3
move $t5 ,$t3
find_max_min_loop:
beqz $t0 ,end_find_max_min # nếu đã duyệt hết các phần tử thì nhảy đến nhãn
end_find_max_min
lw $t3 ,($s1)
bgt $t3 ,$t4 ,update_max
blt $t3 ,$t5 ,update_min
next_element:
subi $s1 ,$s1 ,4
addi $t0 ,$t0 ,-1
update_max:
move $t4 ,$t3
j next_element
update_min:
move $t5 ,$t3
26
j next_element
end_find_max_min:
# In ra giá trị lớn nhất và nhỏ nhất của mảng
li $v0 ,4
la $a0 ,max_msg
syscall
li $v0 ,4
la $a0 ,min_msg
syscall
sum_loop:
beqz $t0 ,end_sum # nếu đã duyệt hết các phần tử thì nhảy đến nhãn end_sum
lw $t3 ,($s1)
add $t6 ,$t6 ,$t3
end_sum:
# In ra tổng các phần tử của mảng
li $v0 ,4
la $a0 ,sum_msg
syscall
# Người sử dụng nhập vào chỉ số của một phần tử nào đó và giá trị của phần tử đó được in ra cửa
sổ
li $v0 ,4
la $a0 ,input_index
syscall # in ra dòng nhắc nhập chỉ số
li $v0 ,5
syscall # đọc số nguyên từ bàn phím là chỉ số của phần tử cần lấy
bltz $v0 ,error_input # nếu chỉ số nhỏ hơn không thì nhảy đến nhãn error_input
bge $v0 ,$s0 ,error_input # nếu chỉ số lớn hơn hoặc bằng số phần tử thì nhảy đến nhãn
error_input
mul $t3 ,$v0 ,$t1 # tính độ dời byte từ đầu mảng đến phần tử cần lấy
add $s1 ,$s2 ,$t3 # cộng với địa chỉ ban đầu của mảng để ra địa chỉ của phần tử cần lấy
27
lw $a0 ,($s1) # lấy giá trị của phần tử cần lấy
print_element:
li $v0 ,4
la $a0 ,element_msg
syscall
li $v0 ,1
syscall # in ra giá trị của phần tử
error_input:
li $v0 ,4
la $a0 ,error_msg
syscall # in ra dòng thông báo lỗi nhập liệu
end_program:
b. Nhập một mảng các số nguyên n phần tử (nhập vào số phần tử và giá trị của
từng phần tử). Mảng này gọi là A.
Chuyển dòng lệnh C dưới đây sang mã assembly của MIPS. Với các biến nguyên i,
j được gán lần lượt vào thanh ghi $s0, $s1; và địa chỉ nền của mảng số nguyên A
được lưu trong thanh ghi $s3
if (i<j) A[i] = i;
else A[i] = j;
slt $t0, $s0, $s1 # gán $t0 bằng 1 nếu i < j, ngược lại gán $t0 bằng 0
beq $t0, $zero, else # nếu $t0 bằng 0 (nghĩa là i >= j), nhảy đến nhãn else
sll $t1, $s0, 2 # tính độ lệch byte của A[i] bằng cách nhân i với 4
else:
sll $t1, $s0, 2 # tính độ lệch byte của A[i] bằng cách nhân i với 4
28
add $t1, $s3, $t1 # tính địa chỉ của A[i]
end:
................................................................................................................................
29
................................................................................................................................
................................................................................................................................
................................................................................................................................
................................................................................................................................
................................................................................................................................
................................................................................................................................
................................................................................................................................
................................................................................................................................
................................................................................................................................
................................................................................................................................
................................................................................................................................
................................................................................................................................
................................................................................................................................
................................................................................................................................
................................................................................................................................
................................................................................................................................
................................................................................................................................
30
MỤC LỤC
Bài 1: abc..............................................................................................................6
Bài 2: efg...............................................................................................................7
Bài 3: zxc...............................................................................................................8
31
Bài 1: Trình bày.
……………………………………………….
32