Skip to content

Instantly share code, notes, and snippets.

@lethienquan28052006
Last active May 19, 2025 02:37
Show Gist options
  • Save lethienquan28052006/ba39a51dc6bb882ccbf06049ea375366 to your computer and use it in GitHub Desktop.
Save lethienquan28052006/ba39a51dc6bb882ccbf06049ea375366 to your computer and use it in GitHub Desktop.

LAB4 IT0012

I. 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:

Ví dụ 1

	.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ủa var1.
  • Sau cùng giá trị ở địa chỉ của var1$5$.

Mô phỏng chạy: image Sau khi thực hiện chương trình image image Địa chỉ của var1$0x1001000$, khi này đã được gán giá trị $5$

Ví dụ 2

    .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 $3$ phần tử và gán array1 = {5, 13, -7}==

Mô phỏng chạy: image Sau khi chạy, ta đã gán được mảng array1 (có địa chỉ $0x1001000$) thành {5, 13, -7} theo mã thập lục phân là {5, d, fffff...9} image

Ví dụ 3

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).
    • $5$ là dịch vụ "read integer" (đọc một số nguyên từ người dùng).
  • 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: image Nhập giá trị $2201$ từ bàn phím image Sau đó chương trình lưu vào thanh ghi $v0 image ($2201_{10} = 899_{16}$)

Ví dụ 4

.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: image Xâu được in ra sau khi chạy chương trình: image

II. Thao tác với mảng

CODE, giải thích:

.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:

Mô phỏng chạy:

image

A. TASK1: In ra 2 mảng array1 và array2:

image

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}

image

  • Hai ô nhớ $(40)$$(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. image

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: image
  • TH2: Nhập và in ra phần tử trong mảng array2: image
  • TH3: Nhập và in ra phần tử trong mảng array3: image

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.

CODE, giải thích:

.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: image 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 image

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

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment