Duy Nguyen Hoang A fully enthusiastic boy

MIPS Architecture Series – Phần 2: Lệnh

6 min read

Trong chuỗi bài viết về Kiến trúc MIPS, chúng ta đã tìm hiểu về cấu trúc và đặc điểm chung của kiến trúc này. Tiếp theo, chúng ta sẽ khám phá các lệnh quan trọng trong MIPS. Các lệnh này cung cấp khả năng thực hiện các phép toán và điều khiển.

Giới thiệu về các loại lệnh trong MIPS

Trong kiến trúc MIPS, có ba loại lệnh chính: R (Register), I (Immediate), và J (Jump).

mips basic format

Lệnh R (Register)

Loại lệnh này sử dụng các thanh ghi (register) để thực hiện các phép toán. Cấu trúc 32 bit của một lệnh R trong MIPS như sau:

  • Opcode (6 bit): Mã lệnh (định nghĩa phép toán).
  • Rs (5 bit): Số hiệu thanh ghi đầu tiên.
  • Rt (5 bit): Số hiệu thanh ghi thứ hai.
  • Rd (5 bit): Số hiệu thanh ghi đích.
  • Shamt (5 bit): Số lượng dịch bit (shift amount).
  • Funct (6 bit): Mã chức năng (xác định phép toán cụ thể).

Lệnh I (Immediate)

Loại lệnh này thực hiện các phép toán sử dụng giá trị ngay tức thì (immediate value) và thanh ghi. Cấu trúc 32 bit của một lệnh I trong MIPS như sau:

  • Opcode (6 bit): Mã lệnh (định nghĩa phép toán).
  • Rs (5 bit): Số hiệu thanh ghi đầu tiên.
  • Rt (5 bit): Số hiệu thanh ghi thứ hai hoặc thanh ghi đích.
  • Immediate (16 bit): Giá trị ngay tức thì.

Lệnh J (Jump)

Loại lệnh này được sử dụng để thực hiện nhảy tới một địa chỉ cụ thể trong chương trình. Cấu trúc 32 bit của một lệnh J trong MIPS như sau:

  • Opcode (6 bit): Mã lệnh (định nghĩa phép toán).
  • Address (26 bit): Địa chỉ nhãn (label) cần nhảy tới.

MIPS Instruction References Table

Bảng mô tả lệnh của kiến trúc MIPS

Bạn có thể tham khảo đầy đủ References Table của MIPS tại đây: https://inst.eecs.berkeley.edu/~cs61c/resources/MIPS_Green_Sheet.pdf

Dưới đây là bảng tham khảo các lệnh thông dụng trong kiến trúc MIPS:

Tên lệnhMnemonicFormatOperation trong VerilogOpcode/Funct
CộngaddRR[rd] = R[rs] + R[rt]100000
TrừsubRR[rd] = R[rs] – R[rt]100010
Cộng (immediate)addiIR[rt] = R[rs] + Immediate001000
Cộng không xử lý tràn sốadduRR[rd] = R[rs] + R[rt]100001
Trừ (immediate)subiIR[rt] = R[rs] – Immediate001001
NhảyjJPC = JumpAddress000010
Nhảy nếu bằng nhaubeqIif (R[rs] == R[rt]) PC = PC + 4 + (Immediate << 2)000100
Nhảy nếu khác nhaubneIif (R[rs] != R[rt]) PC = PC + 4 + (Immediate << 2)000101
Nhảy nếu lớn hơn 0bgtzIif (R[rs] > 0) PC = PC + 4 + (Immediate << 2)000111
Load từ bộ nhớlwIR[rt] = Memory[R[rs] + Immediate]100011
Lưu vào bộ nhớswIMemory[R[rs] + Immediate] = R[rt]101011

Giải thích các thuật ngữ:

  • Immediate: Immediate là giá trị ngay tức thì được sử dụng trong các lệnh I để thực hiện phép toán. Giá trị Immediate được lưu trữ trong trường 16 bit của lệnh I và có thể là một số nguyên dương hoặc số nguyên âm. Khi thực hiện phép toán, giá trị Immediate sẽ được kết hợp với giá trị của thanh ghi để thực hiện phép tính tương ứng.
  • Memory[]: Memory đề cập đến bộ nhớ trong kiến trúc MIPS. Nó là một không gian lưu trữ dùng để lưu trữ dữ liệu và các chỉ thị của chương trình. Trong lệnh lw, giá trị từ bộ nhớ được lấy từ địa chỉ được tính bằng cách cộng giá trị của thanh ghi Rs với giá trị của Immediate.
  • R[]: R đề cập đến thanh ghi (register) trong kiến trúc MIPS. Các thanh ghi là nơi lưu trữ và xử lý dữ liệu trong các lệnh MIPS. Trong các lệnh, chúng ta thực hiện các phép toán trên các thanh ghi R thông qua các chỉ thị như Rs, Rt và Rd.
  • JumpAddress: JumpAddress là địa chỉ đích mà lệnh nhảy (jump) trong MIPS sẽ nhảy tới. Trong lệnh j, giá trị JumpAddress là 26 bit cuối của lệnh J và được kết hợp với các bit cao của địa chỉ hiện tại để xác định địa chỉ mới mà chương trình sẽ nhảy tới.
  • PC: PC (Program Counter) là một thanh ghi trong kiến trúc MIPS lưu trữ địa chỉ hiện tại của lệnh đang được thực thi. Khi chương trình thực hiện lệnh nhảy (jump), giá trị PC sẽ được thay đổi để chỉ định địa chỉ mới mà chương trình sẽ tiếp tục thực thi.

Giải thích và ví dụ các lệnh trong MIPS

Lệnh toán học

  1. Lệnh add thực hiện phép cộng hai số và lưu kết quả vào thanh ghi đích. Ví dụ: add $t0, $t1, $t2 thực hiện cộng giữa giá trị trong thanh ghi $t1$t2, rồi lưu kết quả vào $t0.
  2. Lệnh sub trừ hai số và lưu kết quả vào thanh ghi đích. Ví dụ: sub $t0, $t1, $t2 thực hiện phép trừ giữa giá trị trong thanh ghi $t1$t2, rồi lưu kết quả vào $t0.
  3. Lệnh addi thực hiện phép cộng số ngay tức thì với giá trị trong thanh ghi và lưu kết quả vào thanh ghi đích. Ví dụ: addi $t0, $t1, 5 cộng giá trị trong thanh ghi $t1 với 5, rồi lưu kết quả vào $t0.
  4. Lệnh addu thực hiện phép cộng hai số không xử lý tràn và lưu kết quả vào thanh ghi đích. Ví dụ: addu $t0, $t1, $t2 cộng giá trị trong thanh ghi $t1$t2 mà không quan tâm đến tràn số, rồi lưu kết quả vào $t0.
  5. Lệnh subi trừ số ngay tức thì với giá trị trong thanh ghi và lưu kết quả vào thanh ghi đích. Ví dụ: subi $t0, $t1, 5 trừ giá trị trong thanh ghi $t1 với 5, rồi lưu kết quả vào $t0.

Lệnh nhảy

  1. Lệnh j thực hiện nhảy đến một địa chỉ cố định. Ví dụ: j loop nhảy đến nhãn loop trong chương trình.
  2. Lệnh beq thực hiện nhảy nếu hai giá trị bằng nhau. Ví dụ: beq $t0, $t1, label nếu giá trị trong thanh ghi $t0$t1 bằng nhau, thì nhảy đến nhãn label trong chương trình.
  3. Lệnh bne thực hiện nhảy nếu hai giá trị khác nhau. Ví dụ: bne $t0, $t1, label nếu giá trị trong thanh ghi $t0$t1 khác nhau, thì nhảy đến nhãn label trong chương trình.
  4. Lệnh bgtz thực hiện nhảy nếu giá trị lớn hơn 0. Ví dụ: bgtz $t0, label nếu giá trị trong thanh ghi $t0 lớn hơn 0, thì nhảy đến nhãn label trong chương trình.

Lệnh thao tác bộ nhớ

  1. Lệnh lw load từ bộ nhớ vào thanh ghi. Ví dụ: lw $t0, 0($t1) load giá trị từ địa chỉ 0 + $t1 trong bộ nhớ và lưu vào thanh ghi $t0.
  2. Lệnh sw lưu từ thanh ghi vào bộ nhớ. Ví dụ: sw $t0, 0($t1) lưu giá trị từ thanh ghi $t0 vào địa chỉ 0 + $t1 trong bộ nhớ.

Mô phỏng chương trình đơn giản bằng MIPS

Dưới đây là một ví dụ mô phỏng chương trình đơn giản bằng MIPS. Chương trình này thực hiện các phép toán cộng, trừ, nhân, chia và giải phương trình bậc nhất.

.data
    A:  .word 2
    B:  .word 3
    C:  .word 0

.text
    main:
        lw $t0, A           # Load giá trị của A vào thanh ghi $t0
        lw $t1, B           # Load giá trị của B vào thanh ghi $t1

        add $t2, $t0, $t1   # Tính tổng: $t2 = $t0 + $t1
        sub $t3, $t0, $t1   # Tính hiệu: $t3 = $t0 - $t1
        mul $t4, $t0, $t1   # Tính tích: $t4 = $t0 * $t1
        div $t5, $t0, $t1   # Tính thương: $t5 = $t0 / $t1

        sw $t2, C           # Lưu giá trị tổng vào C

        # Giải phương trình bậc nhất Ax + B = 0
        neg $t1, $t1        # Đảo dấu B
        div $t1, $t0        # Chia B cho A
        mflo $t6            # Lưu kết quả vào $t6

        j end              # Nhảy đến kết thúc chương trình

    end:
        # Kết thúc chương trình

Trong ví dụ này, chúng ta sử dụng các lệnh MIPS như lw, add, sub, mul, div, sw, neg, mflo, và j để thực hiện các phép toán và điều khiển. Kết quả cuối cùng sẽ được lưu trong thanh ghi $t6 và được sử dụng để giải phương trình bậc nhất.

Tổng kết

Trên đây là một cái nhìn tổng quan về các lệnh quan trọng trong kiến trúc MIPS, bao gồm giải thích, ví dụ và một chương trình đơn giản. Hi vọng rằng thông qua bài viết này, bạn đã có cái nhìn sâu hơn về lệnh trong MIPS và cách chúng hoạt động.

Avatar photo
Duy Nguyen Hoang A fully enthusiastic boy

One Reply to “MIPS Architecture Series – Phần 2: Lệnh”

Leave a Reply

Your email address will not be published. Required fields are marked *