.data
var1: .word 23
# Khai báo một biến tên là var1 kiểu word
.text
_start:
lw $t0, var1
# Nạp giá trị của var1 vào thanh ghi $t0.
# Sau đó, giá trị ở thanh ghi $t0 sẽ là 23
li $t1, 5
# Nạp giá trị 5 vào thanh ghi $t1
sw $t1, var1
# Lưu giá trị từ thanh ghi $t1 (đang là 5) vào địa chỉ của var1.
# Sau cùng giá trị ở địa chỉ của var1 là 5
Ý Nghĩa:
- Chương trình tạo biến
var1
có giá trị mặc định là$23$ . - Sau đó nạp giá trị
$23$ đó từvar1
vào$t0
. - Tiếp theo nạp giá trị
$5$ vào thanh ghi$t1
. - Lưu giá trị từ thanh ghi
$t1
(đang là$5$ ) vào địa chỉ củavar1
. - Sau cùng giá trị ở địa chỉ của
var1
là$5$ .
Mô phỏng chạy:
Sau khi thực hiện chương trình
Địa chỉ của
var1
là
.data
array1: .space 12
# Khai báo một vùng nhớ (mảng) tên là array1, cấp phát 12 byte
# Do đó mảng có thể chứa 3 phần tử
.text
_start:
la $t0, array1
# Nạp địa chỉ của array1 vào thanh ghi $t0.
li $t1, 5
# Nạp giá trị tức thời 5 vào $t1.
sw $t1, ($t0)
# Lưu giá trị từ $t1 (là 5) vào địa chỉ mà $t0 đang trỏ tới.
# array1[0] = 5.
li $t1, 13
# Nạp giá trị 13 vào $t1.
sw $t1, 4($t0)
# Lưu giá trị từ $t1 (là 13) vào địa chỉ ($t0 + 4 byte).
# array1[1] = 13.
li $t1, -7
# Nạp giá trị -7 vào $t1.
sw $t1, 8($t0)
# Lưu giá trị từ $t1 (là -7) vào địa chỉ ($t0 + 8 byte).
# array1[2] = -7.
Ý nghĩa:
- Khai báo một vùng nhớ (mảng) tên là
array1
, cấp phát$12$ byte - Do đó mảng có thể chứa
$3$ phần tử - Nạp địa chỉ của
array1
vào thanh ghi$t0
. - Lưu giá trị từ
$t1
(là$5$ ) vào địa chỉ mà$t0
đang trỏ tới.array1[0] = 5.
- Nạp giá trị
$13$ vào$t1
. - Lưu giá trị từ
$t1
(là$13$ ) vào địa chỉ ($t0
+$4$ byte).array1[1] = 13.
- Nạp giá trị
$-7$ vào$t1
. - Lưu giá trị từ
$t1
(là$-7$ ) vào địa chỉ ($t0
+$8$ byte).array1[2] = -7.
==$\Rightarrow$ Tạo mảng array1
chứa array1 = {5, 13, -7}
==
Mô phỏng chạy:
Sau khi chạy, ta đã gán được mảng
array1
(có địa chỉ {5, 13, -7}
theo mã thập lục phân là {5, d, fffff...9}
li $v0, 5
# Nạp giá trị tức thời 5 vào thanh ghi $v0.
# Trong MIPS, thanh ghi $v0 được sử dụng để chứa mã dịch vụ hệ thống (syscall code).
# Mã 5 là dịch vụ "read integer" (đọc một số nguyên từ người dùng).
syscall
# Thực hiện lời gọi hệ thống.
# Hệ thống sẽ dừng và chờ người dùng nhập một số nguyên và lưu vào v0.
Ý Nghĩa
- Nạp giá trị
$5$ vào thanh ghi$v0
.- Trong MIPS, thanh ghi
$v0
được sử dụng để chứa mã dịch vụ hệ thống (syscall code). - Mã
$5$ là dịch vụ "read integer" (đọc một số nguyên từ người dùng).
- Trong MIPS, thanh ghi
- Thực hiện lời gọi hệ thống.
- Hệ thống sẽ dừng và chờ người dùng nhập một số nguyên và lưu vào
$v0
.
==$\Rightarrow$ Nhập giá trị từ bàn phím vào $v0
==
Mô phỏng:
Nhập giá trị
Sau đó chương trình lưu vào thanh ghi
$v0
(
.data
string1: .asciiz "Print this.\n"
# Khai báo một chuỗi ký tự ASCII có tên string1 = "Print this.\n"
.text
main:
li $v0, 4
# Nạp giá trị tức thời 4 vào thanh ghi $v0.
# Mã syscall 4 là dịch vụ "print string" (in một chuỗi ký tự).
la $a0, string1
# Nạp địa chỉ của string1 vào thanh ghi $a0.
# Đối với syscall in chuỗi, thanh ghi $a0 chứa địa chỉ của chuỗi cần in.
syscall
# Thực hiện lời gọi hệ thống.
# Hệ thống sẽ in chuỗi tại địa chỉ trong $a0 ra màn hình console.
Ý nghĩa:
- Khai báo một chuỗi ký tự ASCII có tên
string1
="Print this.\n"
- Nạp giá trị tức thời
$4$ vào thanh ghi$v0
. - Mã syscall
$4$ là dịch vụ "print string" (in một chuỗi ký tự). - Thực hiện lời gọi hệ thống.
- Hệ thống sẽ in chuỗi tại địa chỉ trong
$a0
ra màn hình console.
==$\Rightarrow$ In ra xâu string1
= "Print this.\n"
==
Mô phỏng:
Xâu được in ra sau khi chạy chương trình:
.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
# Các chuỗi thông báo cần thiết
array1_msg: .asciiz "Array 1 elements: "
array2_msg: .asciiz "Array 2 elements: "
newline: .asciiz "\n"
space_char: .asciiz " "
prompt_array_num: .asciiz "Enter array number (1, 2, or 3): "
prompt_index: .asciiz "Enter index: "
element_msg: .asciiz "Element at index "
is_msg: .asciiz " is: "
.text
.globl main
main:
# Nạp địa chỉ cơ sở và kích thước của các mảng vào các thanh ghi $s
la $s0, array1 # $s0 = địa chỉ cơ sở của array1
lw $s3, size1 # $s3 = kích thước của array1
la $s1, array2 # $s1 = địa chỉ cơ sở của array2
lw $s4, size2 # $s4 = kích thước của array2
la $s2, array3 # $s2 = địa chỉ cơ sở của array3
lw $s5, size3 # $s5 = kích thước của array3
# Task 1: In các phần tử của array1 và array2
jal print_arrays_task
# Task 2: Gán giá trị cho array3
jal populate_array3_task
# Task 3: Nhập mảng và chỉ số, sau đó xuất phần tử
jal get_element_from_user_task
# Kết thúc chương trình
j END
#---------------------------------------------------------------------------------------------
# Task 1: In các phần tử của array1 và array2
#---------------------------------------------------------------------------------------------
print_arrays_task:
# ---------------In array1---------------
la $a0, array1_msg # In thông báo "Array 1 elements: "
li $v0, 4
syscall
move $t0, $zero # i = 0 (biến đếm vòng lặp)
move $t1, $s0 # $t1 = con trỏ tới phần tử hiện tại của array1 (ban đầu là array1[0])
# $s3 chứa size1
print_array1_loop:
beq $t0, $s3, end_print_array1_loop # if i == size1, kết thúc vòng lặp
lw $a0, ($t1) # Nạp array1[i] (word) vào $a0 để in
li $v0, 1 # syscall: print_integer
syscall
la $a0, space_char # In một dấu cách
li $v0, 4
syscall
addi $t1, $t1, 4 # Di chuyển con trỏ tới phần tử word tiếp theo (địa chỉ + 4)
addi $t0, $t0, 1 # i++
j print_array1_loop
end_print_array1_loop:
la $a0, newline # In ký tự xuống dòng
li $v0, 4
syscall
# ---------------In array2---------------
la $a0, array2_msg # In thông báo "Array 2 elements: "
li $v0, 4
syscall
move $t0, $zero # i = 0 (biến đếm vòng lặp)
move $t1, $s1
# $t1 = con trỏ tới phần tử hiện tại của array2 (ban đầu là array2[0])
# $s4 chứa size2
print_array2_loop:
beq $t0, $s4, end_print_array2_loop # if i == size2, kết thúc vòng lặp
lb $a0, ($t1)
# Nạp array2[i] (byte) vào $a0 để in. syscall 1 sẽ in giá trị số của nó.
li $v0, 1 # syscall: print_integer
syscall
la $a0, space_char # In một dấu cách
li $v0, 4
syscall
addi $t1, $t1, 1
# Di chuyển con trỏ tới phần tử byte tiếp theo (địa chỉ + 1)
addi $t0, $t0, 1 # i++
j print_array2_loop
end_print_array2_loop:
la $a0, newline # In ký tự xuống dòng
li $v0, 4
syscall
jr $ra # Quay lại hàm gọi (main)
#---------------------------------------------------------------------------------------------
# Task 2: Gán giá trị cho array3
# Công thức: array3[i] = array2[i] + array2[size2 - 1 - i]
# array3 lưu các phần tử byte. i chạy từ 0 đến size3-1 (0 đến 7).
#---------------------------------------------------------------------------------------------
populate_array3_task:
move $t0, $zero # i = 0
move $t1, $s2 # $t1 = địa chỉ cơ sở của array3
addi $t5, $s4, -1 # $t5 = size2 - 1 (tính sẵn để dùng trong vòng lặp)
# $s1 là địa chỉ cơ sở array2
# $s5 là size3 (kích thước của array3, là 8)
populate_array3_loop:
beq $t0, $s5, end_populate_array3_loop # if i == size3, kết thúc
# Lấy array2[i]
add $t6, $s1, $t0 # $t6 = địa chỉ của array2[i] = base_array2 + i
lb $t2, ($t6) # $t2 = array2[i]
# Tính chỉ số thứ hai: index_B = (size2 - 1) - i
sub $t4, $t5, $t0 # $t4 = (size2 - 1) - i
# Lấy array2[index_B]
add $t7, $s1, $t4
# $t7 = địa chỉ của array2[index_B] = base_array2 + index_B
lb $t3, ($t7) # $t3 = array2[index_B]
# Tính tổng: sum = array2[i] + array2[index_B]
add $t2, $t2, $t3 # $t2 = sum
# Lưu kết quả vào array3[i]
sb $t2, ($t1) # array3[i] = sum
addi $t1, $t1, 1
# Di chuyển con trỏ tới phần tử byte tiếp theo trong array3
addi $t0, $t0, 1 # i++
j populate_array3_loop
end_populate_array3_loop:
jr $ra # Quay lại hàm gọi (main)
#---------------------------------------------------------------------------------------------
# Task 3: Người dùng nhập mảng và chỉ số, xuất phần tử tương ứng
#---------------------------------------------------------------------------------------------
get_element_from_user_task:
# Yêu cầu nhập số thứ tự mảng
la $a0, prompt_array_num
li $v0, 4
syscall
li $v0, 5 # syscall: read_integer
syscall
move $t0, $v0 # Lưu lựa chọn mảng vào $t0
# Yêu cầu nhập chỉ số
la $a0, prompt_index
li $v0, 4
syscall
li $v0, 5 # syscall: read_integer
syscall
move $t1, $v0 # Lưu chỉ số vào $t1
# Xử lý dựa trên lựa chọn mảng
beq $t0, 1, process_array1_choice
beq $t0, 2, process_array2_choice
# Nếu không phải 1 hoặc 2, thì là 3 (do đã kiểm tra ở trên)
j process_array3_choice # Hoặc beq $t0, 3, process_array3_choice
process_array1_choice:
# Tính địa chỉ: base_array1 + user_index * 4
mul $t2, $t1, 4 # $t2 = user_index * 4 (offset_bytes)
add $t2, $s0, $t2 # $t2 = địa chỉ array1[user_index]
lw $t3, ($t2) # $t3 = array1[user_index]
j print_element_result
process_array2_choice:
# Tính địa chỉ: base_array2 + user_index (vì là mảng byte)
add $t2, $s1, $t1 # $t2 = địa chỉ array2[user_index]
lb $t3, ($t2) # $t3 = array2[user_index]
j print_element_result
process_array3_choice:
# Tính địa chỉ: base_array3 + user_index (vì array3 lưu byte)
add $t2, $s2, $t1 # $t2 = địa chỉ array3[user_index]
lb $t3, ($t2) # $t3 = array3[user_index]
j print_element_result
print_element_result:
la $a0, element_msg # In "Element at index "
li $v0, 4
syscall
move $a0, $t1 # In chỉ số (user_index)
li $v0, 1
syscall
la $a0, is_msg # In " is: "
li $v0, 4
syscall
move $a0, $t3 # In giá trị phần tử
li $v0, 1
syscall
la $a0, newline # In ký tự xuống dòng
li $v0, 4
syscall
end_get_element_task:
jr $ra # Quay lại hàm gọi (main)
END:
A. TASK1: In ra 2 mảng array1 và array2:
B. TASK2: Gán mảng array3 (array3[i] = array2[i] + array2[size2 - 1 - i])
- Mảng array3 sau ghi được xử lí:
array3 = {17, 17, 17, 17, 17, 17, 17, 17}
- Đổi thành hệ 16:
array3 = {11, 11, 11, 11, 11, 11, 11, 11}
- Hai ô nhớ
$(40)$ và$(44)$ lưu giá trị của mảng array3 - Ô nhớ
$(48)$ lưu giá trị của size3 - Vì là kiểu
word
nên mỗi ô nhớ gồm$4$ byte sẽ lưu được$4$ phần tử của mảng array3.
C. TASK3: Nhập thứ tự và chỉ số mảng, in ra phần tử tương ứng:
- TH1: Nhập và in ra phần tử trong mảng
array1
: - TH2: Nhập và in ra phần tử trong mảng
array2
: - TH3: Nhập và in ra phần tử trong mảng
array3
:
III.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.
.data
msg_n: .asciiz "Nhap n: "
msg_i: .asciiz "Nhap i: "
msg_j: .asciiz "Nhap j: "
msg_kq: .asciiz "Mang sau khi cap nhat:\n"
msg_nhap: .asciiz "Nhap phan tu: "
newline: .asciiz "\n"
.text
.globl main
main:
# In "Nhap n:"
li $v0, 4
la $a0, msg_n
syscall
# Nhap n
li $v0, 5
syscall
add $s2, $zero, $v0 # $s2 = n
# Cap phat mang tren stack: $t0 = n * 4
add $t0, $zero, $s2
sll $t0, $t0, 2 # t0 = n * 4
sub $sp, $sp, $t0
add $s3, $zero, $sp # $s3 = dia chi mang A
# Nhap mang A
add $t1, $zero, $zero # i = 0
nhap_loop:
slt $t4, $t1, $s2
beq $t4, $zero, end_input
li $v0, 4
la $a0, msg_nhap
syscall
li $v0, 5
syscall
add $t2, $zero, $v0
# tinh dia chi A[i]
sll $t3, $t1, 2
add $t3, $t3, $s3
sw $t2, 0($t3)
addi $t1, $t1, 1
j nhap_loop
end_input:
# Nhap i
li $v0, 4
la $a0, msg_i
syscall
li $v0, 5
syscall
add $s0, $zero, $v0
# Nhap j
li $v0, 4
la $a0, msg_j
syscall
li $v0, 5
syscall
add $s1, $zero, $v0
# if (i < j) A[i] = i; else A[i] = j;
slt $t4, $s0, $s1
beq $t4, $zero, ELSE
# THEN: A[i] = i
sll $t5, $s0, 2
add $t5, $t5, $s3
sw $s0, 0($t5)
j END_IF
ELSE:
sll $t5, $s0, 2
add $t5, $t5, $s3
sw $s1, 0($t5)
END_IF:
# In ket qua
li $v0, 4
la $a0, msg_kq
syscall
add $t1, $zero, $zero # i = 0
print_loop:
slt $t4, $t1, $s2
beq $t4, $zero, done
sll $t3, $t1, 2
add $t3, $t3, $s3
lw $a0, 0($t3)
li $v0, 1
syscall
li $v0, 4
la $a0, newline
syscall
addi $t1, $t1, 1
j print_loop
done:
li $v0, 10
syscall
Mô phỏng chạy:
Sau khi thực hiện chương trình, với n = 6, A = [1, 2, 3, 4, 5, 6], i = 3, j = 4
Sau khi thực hiện chương trình, với n = 6, A = [1, 2, 3, 4, 5, 6], i = 4, j = 3