You are on page 1of 36

ĐẠI HỌC QUỐC GIA TP.

HỒ CHÍ MINH
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN
KHOA KỸ THUẬT MÁY TÍNH

BÁO CÁO MÔN HỌC

THỰC HÀNH KIẾN TRÚC MÁY TÍNH


CE119

GIẢNG VIÊN HƯỚNG DẪN: ________________________

SINH VIÊN THỰC HIỆN: __________________________________

TP. HỒ CHÍ MINH, THÁNG 12 NĂM 20xx


ĐẠI HỌC QUỐC GIA TP. HỒ CHÍ MINH
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN
KHOA KỸ THUẬT MÁY TÍNH

BÁO CÁO MÔN HỌC

THỰC HÀNH KIẾN TRÚC MÁY TÍNH


CE119

GIẢNG VIÊN HƯỚNG DẪN: ________________________

SINH VIÊN THỰC HIỆN: __________________________________________

TP. HỒ CHÍ MINH, THÁNG 12 NĂM 20xx

ii
MỤC LỤC

Chương 1. LÀM QUEN VỚI LẬP TRÌNH HỢP NGỮ............................................................1


1.1 Lý thuyết............................................................................................................................. 1
1.1.1. Cách cài đặt Ubuntu, Vim và Perl.............................................................................1
1.1.2. Cách sử dụng Vim.......................................................................................................1
1.1.3. Lí thuyết chương trình hợp ngữ................................................................................3
1.2. Thực hành.......................................................................................................................... 4
1.2.1. Mô phỏng việc thực thi các lệnh................................................................................4
1.2.2. Ý nghĩa của chương trình...........................................................................................5
1.3 Bài tập................................................................................................................................. 5
1.3.1. Khai báo chuỗi và xuất các chuỗi được khai báo.....................................................5
1.3.2. Biểu diễn chuỗi trên dưới bộ nhớ..............................................................................7
1.3.3. Xuất ra đúng chuỗi đã nhập......................................................................................7
1.3.4. Tính tổng hai số nguyên được nhập từ bàn phím.....................................................8
Chương 2. CÁC CẤU TRÚC ĐIỀU KHIỂN...........................................................................11
2.1. Lí thuyết........................................................................................................................... 11
2.1.1. Cấu trúc if, if-else......................................................................................................11
2.1.2. Cấu trúc switch/case.................................................................................................11
2.1.3. Cấu trúc vòng lặp......................................................................................................11
2.2. Thực hành........................................................................................................................ 11
2.2.1. Cấu trúc rẽ nhánh.....................................................................................................11
2.2.2. Cấu trúc vòng lặp......................................................................................................12
2.3. Bài tập.............................................................................................................................. 12
2.3.1. Phân biệt ký tự nhập vào và xuất ký tự liền trước, liền sau..................................12
2.3.2. Tìm số lớn hơn và tính toán theo yêu cầu.................................................................1
Chương 3. CON TRỎ VÀ TRUY XUẤT BỘ NHỚ...................................................................2
i
3.1. Lí thuyết............................................................................................................................. 2
3.1.1. Kiến trúc thanh ghi – thanh ghi.................................................................................2
3.1.2. Làm việc với mảng......................................................................................................2
3.1.3. Làm việc với con trỏ...................................................................................................2
3.1.4. Tại sao nên sử dụng con trỏ.......................................................................................2
3.2. Thực hành.......................................................................................................................... 2
3.2.1. Thao tác với con trỏ....................................................................................................2
3.3. Bài tập................................................................................................................................ 2
3.3.1. Nhập một mảng các số nguyên n phần tử và thực hiện các yêu cầu sau.................2
3.3.2. Nhập một mảng các số nguyên n phần tử.................................................................2
Chương 4. THỦ TỤC (HÀM CON)............................................................................................3
4.1. Lí thuyết............................................................................................................................. 3
4.1.1. Thủ tục......................................................................................................................... 3
4.1.2. Thủ tục với MIPS........................................................................................................3
4.1.3. Ví dụ............................................................................................................................. 3
4.1.4. Lồng thủ tục................................................................................................................3
4.2. Thực hành.......................................................................................................................... 3
4.2.1. In ra cửa sổ I/O giá trị của số int nhập vào cộng thêm 1.........................................3
4.2.2. Tính giá trị biểu thức (a+b) – (c+d) và (a-b) + (c-d).................................................3
4.2.3. Tính giá trị biểu thức (a+b) – (c+d) và (e-f).............................................................3
4.3. Bài tập................................................................................................................................ 3
4.3.1. Tính giai thừa..............................................................................................................3
TÀI LIỆU THAM KHẢO..........................................................................................................4

ii
DANH MỤC HÌNH ẢNH

Danh mục hình ảnh

iii
DANH MỤC BẢNG

Bảng 1.

iv
DANH MỤC TỪ VIẾT TẮT

ABC : nghĩa của ABC

v
CHƯƠNG 1. LÀM QUEN VỚI LẬP TRÌNH HỢP NGỮ
1.1 Lý thuyết
1.1.1. Cách cài đặt Ubuntu, Vim và Perl
Bước 1. Cài ứng dụng Ubuntu trên Windows 10

+ Start → Turn Windows features on or off → Windows Subsystem for Linux


+ Start → Store → Ubuntu → Get → Launch

Bước 2. Cài đặt Perl và Vim trên Ubuntu

+ Sudo apt-get install perl


+ Sudo apt-get install vim
+ Sudo apt-get install vimtutor

Bước 3. Vimtutor để học cách sử dụng Vim.

1.1.2. Cách sử dụng Vim


Bài 1.

- Sử dụng 4 phím h, j, k, l để di chuyển con trỏ lần lượt qua trái, xuống, lên trên, qua phải.
- Khi nhập không chắc chắn, nhấn phím ESC rồi tiến hành nhập lại.
- Để thoát Vim, nhấn phím ESC, nhập :q! rồi nhấn phím ENTER.
- Nhấn phím x để xoá ký tự nằm dưới con trỏ.
- Nhấn phím i để chèn thêm văn bản vào trước con trỏ.
- Nhấn phím a để thêm văn bản.
- Sử dụng :wq để lưu và thoát.

Bài 2.

- Để xoá từ con trỏ đến từ tiếp theo, sử dụng :dw


- Để xoá từ con trỏ đến cuối hàng, sử dụng :d$
- Để xoá một hàng, sử dụng :dd
- Để lặp lại một chuyển động, thêm vào trước nó một số :2w
- Format để thay đổi câu lệnh: operator [number] motion

Trong đó:
+ operator: là lệnh cần thực hiện
+ number: là số lần lặp lại

6
+ motion: là di chuyển qua văn bản để thao tác (w – word, $ – đến cuối
hàng)
- Để di chuyển về đầu hàng, sử dụng :0 (:zero)
- Để hoàn tác hành động trước, sử dụng :u
- Để hoàn tác những thay đổi trên một hàng, sử dụng :U
- Để hoàn tác những gì đã bỏ, sử dụng tổ hợp phím Ctrl+R

Bài 3.

- Để trở về văn bản vừa bị xoá: p, đặt những văn bản bị xoá sau con trỏ.
- Để thay thế ký tự tại chân con trỏ: r
- Ấn ce để thay đổi từ con trỏ đến cuối một từ.
- Ấn c$ để thay đổi đến cuối hàng.

Bài 4.

- ctrl + G : hiển thị vị trí trong file và trạng thái của file
+ G: di chuyển đến cuối file
+ Number G: di chuyển đến hàng số đã điền
+ gg: di chuyển đến hàng đầu tiên
- Nhấn / để tìm một cụm từ theo sau một cụm từ
+ Tìm một cụm từ một lần nữa, nhấn n
+ Tìm một cụm từ giống vậy ở hướng ngược lại, nhấn N
- Tìm cụm từ theo hướng lùi, nhấn ? thay cho /
- Để trở về từ nơi bạn nhấn: Ctrl + O (giữ Ctrl trong lúc nhấn o), lặp lại để trở về. Nhấn
Ctrl + I để tiến tới
- Nhấn % trong lúc con trỏ đang ở (, [, { để tìm ra ), ], } phù hợp còn lại (dễ debug hơn)
- Thay thế mới cho cái cũ nhất trong một hàng, nhấn :s/old/new
- Thay mới mới cho tất cả cái cũ trên một hàng, nhấn :s/old/new/g
- Thay thế những cụm từ giữa 2 hàng #, nhấn :#,#s/old/new/g
- Thay thế tất cả lần xuất hiện trong một file, nhấn :%s/old/new/g
- Để hỏi xác nhận sau mỗi lần thêm ‘c’, nhấn :%s/old/new/gc

Bài 5.

- :!command thi hành một câu lệnh


- :w FILENAME: viết file Vim hiện tại với tên FILENAME
- v montion :w FILENAME: lưu những dòng được chọn trong file FILENAME
7
- :r FILENAME: lấy lại đĩa FILENAME và đặt nó dưới vị trí con trỏ
- :r !dir: đọc output của lệnh dir và đặt nó dưới vị trí con trỏ

Bài 6.

- Gõ o để mở một hàng dưới con trỏ và bắt đầu chế độ Insert


- Gõ O để mở một hàng trên con trỏ
- Gõ a để chèn văn bản sau con trỏ
- Gõ A để chèn văn bản sau hàng cuối cùng
- Gõ e để di chuyển câu lệnh tới cuối từ
- y để sao chép văn bản, p để dán
- Nhấn R in hoa để thay thế chế độ Replace cho đến khi phím <ESC> được nhấn
- Gõ “:set xxx” cài lựa chọn cho “xxx”
- Bỏ trước “no” để một lựa chọn tắt: :set noic

Bài 7.

- Gõ :help hoặc nhấn F1 để mở cửa sổ trợ giúp


- Gõ :help cmd để tìm trợ giúp trên cmd
- Gõ ctrl + W ctrl + W để nhảy đến một cửa sổ khác
- Gõ :q để đóng cửa sổ trợ giúp
- Gõ : command, nhấn ctrl + D để nhìn những hoàn thành khả dụng, nhấn phím <Tab> để
sử dụng một hoàn thành

1.1.3. Lí thuyết chương trình hợp ngữ


1.1.3.1. Bộ nhớ
- Lưu dữ liệu theo byte, half, word.
- Một ký tự được lưu trong 1 byte.
- Một số nguyên được lưu trong 1 word.
- Một lệnh được lưu trong 1 word.

1.1.3.2. Biểu diễn thông tin


- Kí số:
+ Hệ thập phân: Viết bình thường (17)
+ Hệ thập lục phân: Thêm tiền tố 0x (0x11)
- Ký tự: Đặt trong cặp nháy đơn (‘d’)
- Chuỗi: Đặt trong cặp nháy kép (“Integrated circuit”) hoặc (“d”)

1.1.3.3. Thanh ghi


- Có 32 thanh ghi đa dụng (từ 0->31).
8
- Biểu diễn: Tiền tố $ theo sau là chỉ số hoặc tên ($2 hay $sp).
- Thanh ghi Hi và Lo được dành riêng cho phép nhân và phép chia (mfhi , mflo).
- Qui ước:
+ $at dành cho Trình biên dịch hợp ngữ, $k0 và $k1 dành cho OS.
+ $gp, $sp, $fp, $ra dành cho các lệnh chuyên biệt, không nên sử dụng để lưu trữ
tạm trong quá trình tính toán.

1.1.3.4. Cấu trúc chương trình


# Chú thích bằng ký tự #
.data # Khai báo dữ liệu ngay sau hàng này
# Khai báo dữ liệu
.text # Viết chương trình ngay sau hang này
main: # Nhãn thể hiện bắt đầu chương trình
# Viết chương trình

1.1.3.5. Khai báo dữ liệu


[<nhãn>:] .<kiểu dữ liệu> <danh sách giá trị>
- Ví dụ:
+ var1: .word 3 # biến nguyên var1 có kích thước 1 word và giá trị là 3
+ arr1: .byte ‘a’,’k’ # mảng arr1 có 2 phần tử, mỗi phần tử 1 byte
+ arr2: .space 40 # mảng arr2 có kích thước 40 byte liên tục
+ str1: .ascciz “ahihi” # chuỗi str1 có kết thúc bởi null

1.2. Thực hành


1.2.1. Mô phỏng việc thực thi các lệnh
Bảng 1.1 – Chức năng của một số lệnh trong MIPS
STT LỆNH VÍ DỤ CHỨC NĂNG
1 add add $t1, $t2, $t3 Gán $t1 là tổng của giá trị tại $t2 và $t3
2 addi addi $t1, $t2, -100 Gán $t1 là tổng của giá trị tại $t2 và giá trị bất kỳ
3 addu addu $t1, $t2, $t3 Tương tự lệnh add, kết quả trả về là số không dấu
4 addiu addiu $t1, $t2, -100 Tương tự lệnh addi, kết quả trả về là số không dấu
5 sub sub $t1, $t2, $t3 Gán $t1 là kết quả phép trừ giữa giá trị tại $t2 và $t3
6 subu subu $t1, $t2, $t3 Tương tự lệnh sub, kết quả trả về là số không dấu
7 and and $t1, $t2, $t3 Gán $t1 là “and” của các giá trị luận lý tại $t2 và $t3
8 andi andi $t1, $t2, 100 Gán $t1 là “and” của giá trị luận lý tại $t2 & giá trị bất kỳ
9 or or $t1, $t2, $t3 Gán $t1 là “or” của các giá trị luận lý tại $t2 và $t3
10 nor nor $t1, $t2, $t3 Gán $t1 là “nor” của các giá trị luận lý tại $t2 và $t3
11 lw lw $t1, label Đưa giá trị của label vào thanh ghi $t1 ở kiểu word
9
12 sw sw $t1, label Lưu giá trị kiểu word tại thanh ghi $t1 vào địa chỉ label
13 slt slt $t1, $t2, $t3 Nếu $t2 < $t3 thì $t1 = 1, nếu không thì $t1 = 0
14 slti slti $t1, $t2, -100 Nếu $t2 < -100 thì $t1 = 1, nếu không thì $t1 = 0
15 sltu sltu $t1, $t2, $t3 Tương tự lệnh slt nhưng dùng quy tắc so sánh không dấu
16 sltiu sltiu $t1, $t2, -100 Tương tự lệnh slti nhưng dùng quy tắc so sánh không dấu
syscal
17 Gọi chức năng nhập xuất tuỳ thuộc theo giá trị của $v0
l
1.2.2. Ý nghĩa của chương trình
Bảng 1.2 – Ý nghĩa của các chương trình mẫu
STT Chương trình Ý nghĩa
.data
var1: .word 23 var1 = 23

.text
1 __start: $t0 = *var1
lw $t0, var1 $t1 = 5
li $t1, 5 var1 = $t1
sw $t1, var1
.data
array1: .space 12 array1[12], array1=&array1[0]
.text
__start: la $t0, array1 $t0 = array1 = &array1[0]
li $t1, 5 $t1 = 5
2 array1[0] = 0($t0) = $t1 = 5
sw $t1, ($t0)
li $t1, 13 $t1 = 13
sw $t1, 4($t0) array1[1] = 4($t0) = $t1 = 13
li $t1, –7 $t1 = –7
sw $t1, 8($t0) array1[2] = 8($t0) = $t1 = –7
li $v0, 5 $v0 = 5
3
syscall Gọi syscall với chức năng đọc số nguyên

.data string1 = “Print this.\n\0”


string1: .asciiz “Print this.\n”

4 .text $v0 = 4
main: li $v0, 4 $a0 = &string1
la $a0, string1 Gọi syscall với chức năng xuất chuỗi,
syscall với $a0 chứa địa chỉ của chuỗi kết thúc
bằng null
1.3 Bài tập
1.3.1. Khai báo chuỗi và xuất các chuỗi được khai báo
a. Đề bài:
Khai báo và xuất ra cửa sổ I/O 2 chuỗi có giá trị như sau:

10
- Chuỗi 1: Chao ban! Ban la sinh vien nam thu may?
- Chuỗi 2: Hihi, minh la sinh vien nam thu 1 ^-^
b. Sơ đồ giải thuật:

Bắt đầu

$v0 = 4
$a0 = &chuoi1

Syscall
(Xuất chuỗi thứ nhất)

$v0 = 4
$a0 = &chuoi2

Syscall
(Xuất chuỗi thứ hai)

Kết thúc

Hình 1.1 – Sơ đồ giải thuật xuất chuỗi được khai báo

c. Chương trình:
.data
chuoi1: .asciiz "Chao ban! Ban la sinh vien nam thu may?\n"
chuoi2: .asciiz "Hihi, minh la sinh vien nam thu 1 ^-^\n"
.text
main:
lui $1, 0x00001001
ori $4, $1, 0x00000000
addiu $2, $0, 0x00000004
syscall
lui $1, 0x00001001
ori $4, $1, 0x00000029
addiu $2, $0, 00000004
syscall

11
1.3.2. Biểu diễn chuỗi trên dưới bộ nhớ
Các chuỗi trên được mã hóa vào trong thanh ghi dưới dạng mã thập lục phân.

Hình 1.2 – Biểu diễn chuỗi dưới bộ nhớ

1.3.3. Xuất ra đúng chuỗi đã nhập


a. Đề bài:

Nhập chuỗi và xuất ra đúng chuỗi đã nhập. Ví dụ:

- Nhập: Truong Dai hoc Cong nghe thong tin


- Xuất: Truong Dai hoc Cong nghe thong tin

b. Sơ đồ giải thuật:

Bắt đầu

$a0 = &chuoi
$a1 = 100

$v0 = 8, Syscall
(Nhập chuỗi)

$v0 = 4, Syscall
(Xuất chuỗi)

Kết thúc

Hình 1.3 – Sơ đồ giải thuật xuất đúng chuỗi đã nhập

12
c. Chương trình:
.data
chuoi: .asciiz "\0"
.text
main:
lui $1, 0x00001001
ori $4, $1, 0x00000000
addiu $5, $0, 0x00000064
addiu $2, $0, 0x00000008
syscall
addiu $2, $0, 0x00000004
syscall

1.3.4. Tính tổng hai số nguyên được nhập từ bàn phím


a. Đề bài:

Nhập vào 2 số nguyên, sau đó xuất tổng của 2 số nguyên này.

b. Sơ đồ giải thuật:

Bắt đầu

$v0 = 5, Syscall
(Nhập số nguyên)

(Lưu giá trị số nguyên thứ nhất) $a1 = $v0 + $0

$v0 = 5, Syscall
(Nhập số nguyên)

$a2 = $v0 + $0 (Lưu giá trị số nguyên thứ hai)

$a0 = $a1 + $a2 (Tính tổng)

$v0 = 1, Syscall
(Xuất số nguyên $a0)

Kết thúc

Hình 1.4 – Sơ đồ giải thuật tính tổng hai số nguyên nhập từ bàn phím

13
c. Chương trình:

.text
main:
addiu $2, $0, 0x00000005
syscall
add $5, $2, $0
addiu $2, $0, 0x00000005
syscall
add $6, $2, $0
add $4, $5, $6
addiu $2, $0, 0x00000001
syscall

14
CHƯƠNG 2. CÁC CẤU TRÚC ĐIỀU KHIỂN
2.1. Lí thuyết
2.1.1. Cấu trúc if, if-else
- Đầu tiên thực hiện việc so sánh điều kiện
+ So sánh bằng (a == b)
+ So sánh không bằng (a != b)
+ So sánh bé hơn, bé hơn hoặc bằng (a < b, a <= b)
+ So sánh lớn hơn, lớn hơn hoặc bằng (a > b, a >= b)
- Nếu điều kiện đúng, thực hiện lệnh và có thể là đoạn lệnh ở bên trong, nếu sai thì không
thực thi đoạn mã.

2.1.2. Cấu trúc switch/case


- Kiểm tra từng điều kiện để đưa vào trường hợp đúng tương ứng.
- Có thể chuyển thành cấu trúc if, if-else.

2.1.3. Cấu trúc vòng lặp


- Kiếm tra điều kiện, để quyết định có nhảy hay không, điều kiện không thỏa thì thoát.

2.2. Thực hành


2.2.1. Cấu trúc rẽ nhánh
Chuyển đoạn code trong bảng theo sau sang MIPS.

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)

Trả lời:
.text
main:
beq $16, $17, cong
sub $18, $8, $9
j exit
cong:
add $18, $8, $9
exit:

15
2.2.2. Cấu trúc vòng lặp
Chuyển đoạn code trong bảng theo sau sang MIPS.

int Sum = 0;
for (int i = 1; i <= N; ++i) {
Sum = Sum + 1;
}

(Với giá trị của i, N, Sum lần lượt chứa trong các thanh ghi $s0, $s1, $s2)

Trả lời:
.text
main:
add $18, $0, $0
addiu $16, $0, 0x00000001
loop:
slt $8, $17, $16
bne $8, $0, exit
add $18, $18, $16
addi $16, $16, 0x00000001
j loop
exit:

2.3. Bài tập


2.3.1. Phân biệt ký tự nhập vào và xuất ký tự liền trước, liền sau.
a. Đề bài:

Nhập một ký tự từ bàn phím và thực hiện theo yêu cầu.

 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”.
 Xuất ra cửa sổ ký tự liền trước và liền sau của ký tự nhập vào.

Ví dụ:
Nhap ky tu: b
Chu thuong
Ky tu truoc: a
Ky tu sau: c

b. Sơ đồ giải thuật:
16
Bắt đầu

$v0 = 12, Syscall


(Nhập kí tự)

$s0 = $v0 (Lưu kí tự vào $s0)

$s0>47 && Đ $v0 = 4, Syscall


$s0<58 Xuất “Chu so”

$s0>64 && Đ $v0 = 4, Syscall


$s0<91 Xuất “Chu hoa”

$s0>96 && Đ $v0 = 4, Syscall


$s0<123 Xuất “Chu hoa” $t1 = $s0 – 1

S
$v0 = 11, Syscall
$v0 = 4, Syscall Xuất kí tự trước $t1
Xuất “invalid Type”

$v0 = 11, Syscall


Xuất kí tự sau $t2 $t2 = $s0 + 1

Kết thúc

Hình 2.1 – Sơ đồ giải thuật phân loại ký tự và tìm ký tự trước sau

c. Chương trình

17
.data
so: .asciiz "Chu so"
hoa: .asciiz "Chu hoa"
thg: .asciiz "Chu thuong"
khac: .asciiz "Invalid type"

.text
main:
addiu $2, $0, 0x0000000c
syscall
addi $16, $2, 0x00000000

addi $1, $0, 0x0000002f


slt $8, $1, $16
slti $9, $16, 0x0000003a
and $10, $9, $8
bne $10, $0, c_so

addi $1, $0, 0x00000040


slt $8, $1, $16
slti $9, $16, 0x0000005b
and $10, $9,$8
bne $10, $0, c_hoa

addi $1, $0, 0x00000060


slt $8, $1, $16
slti $9, $16, 0x0000007b
and $10, $9,$8
bne $10, $0, c_thg

j c_khac

c_so:
lui $1, 0x00001001
ori $4, $1, 0x00000000
addiu $2, $0, 0x00000004
syscall
j xuat

18
c_hoa:
lui $1, 0x00001001
ori $4, $1, 0x00000005
addiu $2, $0, 0x00000004
syscall
j xuat
c_thg:
lui $1, 0x00001001
ori $4, $1, 0x0000000f
addiu $2, $0, 0x00000004
syscall
j xuat
c_khac:
lui $1, 0x00001001
ori $4, $1, 0x0000001c
addiu $2, $0, 0x00000004
syscall
j xuat

xuat:
addi $9, $16, 0xffffffff
addi $4, $9, 0x00000000
addiu $2, $0, 0x0000000b
syscall
addi $10,$16, 0x00000001
addi $4, $10, 0x00000000
addiu $2, $0, 0x0000000b
syscall

2.3.2. Tìm số lớn hơn và tính toán theo yêu cầu


a. Đề bài:

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, thương của hai số.

b. Sơ đồ giải thuật:

19
Bắt đầu

Khởi tạo nhap[2]

$v0 = 5, Syscall
Nhập số thứ nhất

nhap[0] = nhap[1] = $v0

$v0 = 5, Syscall
Nhập số thứ hai

Đ S
nhap[0] = $v0 nhap[0] < $v0 nhap[1] = $v0

$v0 = 1, Syscall
Xuất nhap[0]
(nhap[0] là số lớn hơn)

$t0 = nhap[0]
$t1 = nhap[1]

$a0 = $t0 + $t1 $a0 = $t0 – $t1 $a0 = $t0 × $t1 $a0 = $t0 ÷ $t1

$v0 = 1, Syscall
Xuất số nguyên

Kết thúc

Hình 2.2 – Sơ đồ thuật toán tìm số lớn hơn và tính toán

c. Chương trình:
20
.data
nhap:.space 2

.text

main:
# Nhap so1
addiu $2, $0, 0x00000005
syscall

lui $1, 0x00001001


ori $16, $1, 0x00000000

sb $2, 0x00000000($16)
sb $2, 0x00000004($16)

# Nhap so2
addiu $2, $0, 0x00000005
syscall

# So sanh
lb $3, 0x00000000($16)
slt $8, $3, $2
bne $8, $0, so2lon

# So1 lon
sb $2, 0x00000004($16)
j tinhtoan

so2lon:
sb $2, 0x00000000($16)

tinhtoan:
lb $8, 0x00000000($16) #L
lb $9, 0x00000004($16) #B

xuat:
lb $4,0x00000000($16)
addiu $2, $0,0x00000001
syscall

21
tong: add $4, $8, $9
addiu $2, $0,0x00000001
syscall

hieu: sub $4, $8, $9


addiu $2, $0,0x00000001
syscall

tich: mul $4, $8, $9


addiu $2, $0,0x00000001
syscall

bne $9, $0, thuong


break
thuong: div $8, $9
mflo $4
addiu $2, $0,0x00000001
syscall

22
Chương 3. CON TRỎ VÀ TRUY XUẤT BỘ NHỚ
3.1. Lí thuyết
3.1.1. Kiến trúc thanh ghi – thanh ghi
- Ví dụ:
int a = 7;
int b = 5;
int c;
c = a + b;
- Ý tưởng: đưa giá trị từng biến a, b, c ở các ô nhớ vào từng thanh ghi trong tập thanh ghi
(của CPU), tiến hành tính toán và đưa vào thanh ghi, sau đó đưa kết quả vào các ô nhớ.
- Chương trình:
.data
addrA: .word 7
addrB: .word 5
addrC: .word
.text
main:
lui $1, 0x00001001
lw $8, 0x00000000($1)

lui $1, 0x00001001


lw $9, 0x00000004($1)

add $10, $9, $8

lui $1, 0x00001001


sw $10,0x00000008($1)

3.1.2. Làm việ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 tạo 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”

23
- Ví dụ:
clear1(int array[], int size) {
int i;
for (i = 0; i < size; i++)
array[i] = 0;
}

- Ý tưởng: $a0 là địa chỉ của array, $a1 là kích thước của array (size), lần lượt tìm địa chỉ
của các phần tử mảng kế tiếp (bằng cách cộng lần lượt 0, 4, 8, 12, ... vào địa chỉ mảng
$a0) và lưu giá trị 0 tại đó, lặp lại đến khi biến i ($t0) không nhỏ hơn kích thước mảng
($a1)
- Chương trình:
.text
add $8, $0, $0
loop:
sll $9, $8, 0x00000002
add $10, $4, $9
sw $0, 0x00000000($10)
addi $8, $8, 0x00000001
slt $11, $8, $5
bne $11, $0, loop

3.1.3. Làm việc với con trỏ


- Con trỏ là một biến lưu địa chỉ của một biến khác. Thao tác với con trỏ trong MIPS là
thao tác trực tiếp với địa chỉ bộ nhớ.
- Ví dụ:
clear2(int *array, int size) {
int *p;
for (p = &array[0]; p < &array[size];
p++)
*p = 0;

- Ý tưởng: $a0 là địa chỉ của array, $a1 là kích thước của array (size), con trỏ $t0 là địa chỉ
phần tử đầu tiên, $t2 là địa chỉ của phần tử cuối cùng (qua tính toán), sau đó lặp lại việc
thay đổi giá trị tại con trỏ ($t0=0) và dời con trỏ sang địa chỉ của phần tử kế tiếp ($t0+=4)
cho đến khi con trỏ $t0 không nhỏ hơn $t2 (địa chỉ phần tử cuối).

24
- Chương trình:
.text
add $8, $0, $4
sll $9, $5, 0x00000002
add $10,$4,$9
loop:
sw $0, 0x00000000($8)
addi $8, $8, 0x00000004
slt $11, $8, $10
bne $11, $0, loop

3.1.4. Lý do nên sử dụng con trỏ


- Tốc độ nhanh hơn (vì số câu lệnh trong vòng lặp (LOOP) khi sử dụng con trỏ ít hơn khi
sử dụng mảng).
- Đúng với bản chất của việc truy xuất bộ nhớ.

3.2. Thực hành


3.2.1. Thao tác với mảng
Cho 3 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

array2: .byte 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16


size2: .word 16

array3: .space 8
size3: .word 8
Mảng array1 có 10 words, kích thước được lưu trong size1; Mảng array2 có 16 bytes, kích
thước được lưu trong size2; Mảng array3 có 8 bytes, kích thước được lưu trong size3.

Viết code 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.
25
Trả lời:
Yêu cầu 1: xuất các phần tử của mảng array1 và array2 ra cửa sổ I/O:
- Ý tưởng: truy xuất phần tử của mảng theo chỉ số mảng, tức nghĩa là dựa vào chỉ số
mảng để tính toán địa chỉ của phần tử đang xét (mảng array1 với mỗi phần tử kiểu
word có độ lớn 4 bytes, mảng array2 với mỗi phần tử có độ lớn 1 byte), lặp lại các
công đoạn tính toán đến khi chỉ số mảng không nhỏ hơn kích thước mảng.
- Ta có sơ đồ thuật toán như sau:

Bắt đầu

$t0 = 0 $t0 = 0
$t1 = size1 $t2 = size2
$a1 = &array1 $a2 = &array2

$a0 = &array1[$t0] $a0 = &array2[$t0]

$v0 = 1, Syscall $v0 = 1, Syscall


Xuất phần tử mảng Xuất phần tử mảng

$t0 = $t0 + 1 $t0 = $t0 + 1

Đ S Đ S
$t0 < $t1 $t0 < $t2

Kết thúc

Hình 3.1 – Sơ đồ thuật toán xuất các phần tử của mảng array1 và array2

Yêu cầu 2: thực hiện gán các giá trị lần lượt cho từng phần tử của mảng array3 theo biểu
thức array3[i] = array2[i] + array2[size2 – 1 – i]
- Ý tưởng: truy xuất phần tử của mảng theo chỉ số mảng (tương tự như yêu cầu 1),
tuy nhiên việc tính toán địa chỉ của phần tử array2[size2 – 1 – i] có hơi khác so với
26
phần tử array2[i] ở chỗ ta phải tính ra địa chỉ của phần tử cuối cùng của mảng
array2 trước.
- Ta có sơ đồ thuật toán như sau:

Bắt đầu

$t0 = 0
$t3 = size3
$a3 = &array3

$t2 = size2 – 1
$a2 = &array2

$s1 = &array3[$t0]
$s2 = &array2[$t0]
$s3 = &array2[size2 – 1 – $t0]

$t4 = *($s2)
$t5 = *($s3)
$t6 = $t5 + $t4

*($s1) = $t6

$t0 = $t0 + 1

$t0 < $t3


Đ

Kết thúc

Hình 3.2 – Sơ đồ thuật toán thực hiện gán các giá trị cho các phần tử mảng array3

Yêu cầu 3: xuất ra phần tử tuỳ chọn tương ứng

27
- Ý tưởng: nếu số nguyên đầu tiên nhập vào là 1 thì truy xuất mảng array1, nếu là 2
thì truy xuất mảng array2; thực hiện việc truy xuất phần tử có chỉ số là số nguyên
nhập vào thứ hai tương tự như cách tính ở 2 yêu cầu trên.

- Ta có sơ đồ thuật toán như sau:

Bắt đầu

$v0 = 5, Syscall
Nhập số nguyên

$s0 là 1 (array1)
$s0 = $v0
hoặc 2 (array2)

$v0 = 5, Syscall
Nhập số nguyên

$s1 là chỉ số phần tử


$s1 = $v0
của mảng

$s0 == 1

$a0 = array1[$s1] $a0 = array2[$s1]

$v0 = 1, Syscall
Xuất số nguyên

Kết thúc

Hình 3.3 – Sơ đồ thuật toán xuất ra phần tử tuỳ chọn


28
Chương trình:

3.2.2. Thao tác với con trỏ


Thực hiện lại nội dung “Thao tác với mảng” với con trỏ.
Trả lời:
- Ý tưởng: truy xuất phần tử bằng chỉ số mảng thì trong điều kiện dừng, biến chạy
phải so sánh với kích thước mảng, còn khi thao tác với con trỏ thì biến con trỏ
phải so sánh với một biến con trỏ khác chứa địa chỉ của phần tử cuối cùng.
- Sơ đồ giải thuật:

Bắt đầu

$t0 = &array1[0] $t0 = &array2[0] $t0 = &array3[0]


$t1 = &array1[size1 – 1] $t2 = &array2[size1 – 1] $t3 = &array3[size3 – 1]
$s2 = &array2[$t0]
$a0 = *($t0) $a0 = *($t0) $s3 = &array2[size2 – 1 – $t0]

$v0 = 1, Syscall $v0 = 1, Syscall


Xuất số nguyên Xuất số nguyên *($t0) = *($s2) + *($s3)

$t0 = $t0 + 1 $t0 = $t0 + 1 $t0 = $t0 + 1

Đ S Đ S
$t0 < $t1 $t0 < $t2 Đ $t0 < $t2

$v0 = 5, Syscall $v0 = 5, Syscall


Nhập số nguyên Nhập số nguyên

$s0 == 1
$s0 = $v0 $s1 = $v0

$a0 = array1[$s1] $a0 = array2[$s1]

$v0 = 1, Syscall
Xuất số nguyên

Kết thúc

29
Hình 3.4 – Sơ đồ giải thuật bài toán thao tác với con trỏ

- Chương trình:
3.3. Bài tập
3.3.1. Bài tập 1
a. Đề bài:

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ử), xuất ra cửa sổ I/O của MARS theo từng yêu cầu sau:

 Xuất ra giá trị lớn nhất và nhỏ nhất của mảng.


 Tổng tất cả các phần tử của mảng.
 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ổ.

b. Sơ đồ giải thuật:

c. Chương trình:

3.3.2. Bài tập 2


a. Đề bài:

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ử), xuất ra cửa sổ I/O của MARS theo từng yêu cầu sau:

 Xuất ra giá trị lớn nhất và nhỏ nhất của mảng.


 Tổng tất cả các phần tử của mảng.
 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ổ.

b. Sơ đồ giải thuật:

c. Chương trình:

30
CHƯƠNG 4. THỦ TỤC (HÀM CON)
4.1. Lí thuyết
4.1.1. Thủ tục
- Quy trình thực hiện:

Lệnh A Gọi thủ tục Thực thi thủ tục

Quay về chương trình chính Lệnh C …

Hình 4.1 – Quy trình thực hiện lời gọi thủ tục

4.1.2. Thủ tục với MIPS


Bước 1. Chuẩn bị đối số.
Bước 2. Lưu trạng thái.
Bước 3. Nhảy tới thủ tục.
Bước 4. Thực thi thủ tục.
Bước 5. Chuẩn bị kết quả.
Bước 6. Quay về chương trình chính (tại lệnh kế tiếp).
 Quy ước:
+ Thanh ghi đối số: $a0 - $a3
+ Thanh ghi kết quả: $v0, $v1
+ Thanh ghi tạm: $t0 - $t9
+ Thanh ghi lưu trữ: $s0 - $s7
+ Thanh ghi địa chỉ trả về: $ra
+ Thanh ghi con trỏ ngăn xếp: $sp
 Lưu ý: phải bảo toàn dữ liệu trong ngăn xếp trước khi gọi thủ tục

31
4.1.3. VÍ DỤ
void main ( ) {
int s = 0;
s = sum(15,12);
}
int sum(int a, int b) {
int t = a + b;
return t;
}

add $s0, $0, $0

addi $a0, $0, 15

add $a1, $0, 12

jal sumPro

add $s0, $0, $v0

j exit

sumPro:

add $v0, $a0, $a1

jr $ra

exit:

4.1.4. LỒNG THỦ TỤC


Bước 1. Chuẩn bị đối số.
Bước 2. Lưu trạng thái.
Bước 3. Nhảy tới thủ tục.
Bước 4. Thực thi thủ tục.
Bước 5. Chuẩn bị kết quả.
Bước 6. Quay về chương trình chính (tại lệnh kế tiếp).
 Lưu ý: Trước khi gọi thủ tục khác phải lưu lại thanh ghi $ra rồi mới nhảy tới thủ tục mới
(Nếu muốn chắc chắn có thể lưu lại thanh ghi $sp).

32
4.2. Thực hành
4.2.1. IN RA CỬA SỔ I/O GIÁ TRỊ CỦA SỐ INT NHẬP VÀO CỘNG THÊM 1
abc

4.2.2. TÍNH GIÁ TRỊ BIỂU THỨC (A+B) – (C+D) VÀ (A-B) + (C-D)
abc

4.2.3. TÍNH GIÁ TRỊ BIỂU THỨC (A+B) – (C+D) VÀ (E-F)


abc

4.3. Bài tập


4.3.1. TÍNH GIAI THỪA
abc

33
TÀI LIỆU THAM KHẢO
[1] Làm quen cách sử dụng Vim với Vimtutor, http://notes.viphat.work/vimtutor

34

You might also like