Áp dụng stack vào thủ tục sum trong MIPS

Em có đoạn code về assemply liên quan đến stack trong MIPS. Anh/chị có thể giúp em viết thủ tục sum để tính tổng các giá trị của các phần tử trong stack không ạ?

  .data
    tb1: .asciiz "Input N = "
    tb2: .asciiz "Output: "
    tb3: .asciiz "Input elements: "
    tb4: .asciiz "Nhap lai: "
    tb5: .asciiz "\nTong la: "
    space: .asciiz "  "
    .text
    main:
    la $a0, tb1 
    li $v0, 4
    syscall
    li $t0,0
    j input_N

    nhaplai:
    la $a0,tb4
    li $v0,4
    syscall

    input_N:
    li $v0, 5 
    syscall
    move $s0, $v0 
    move $s1, $s0 

    blt $s1, 1, nhaplai
    la $a0,tb3
    li $v0,4
    syscall

    loop1:
    beqz $s1, xuat_tb
    li $v0, 5 
    syscall
    move $a0, $v0
    jal pushback
    addi $s1, $s1, -1
    j loop1

    xuat_tb:
    la $a0, tb2 
    li $v0, 4 
    syscall
    move $s1, $s0 

    out:
    beqz $s1, end_program
    move $a0, $v0
    li $v0, 1 
    syscall
    add $t0,$t0,$a0
    la $a0, space 
    li $v0, 4
    syscall
    addi $s1, $s1, -1
    j out
    jr $ra

    xuat_tb5:
    la $a0, tb5 
    li $v0, 4 
    syscall

    pushback:
    addi $sp, $sp, -4 
    sw $a0, 0($sp)
    jr $ra

    popback:
    lw $v0, 0($sp) 
    addi $sp, $sp, 4
    jr $ra

    end_program:

Hm, cậu nên là người tự viết thủ tục đó. Giải thuật cũng không nên quá phức tạp (thậm chí nó còn dễ hơn việc implement stack).

Ngoài ra, tớ có một số best practice advice cho cậu ở code MIPS kể trên:

  • Cậu luôn cần comment cho từng dòng khi code MIPS. Nếu cậu không làm được điều đó, cậu sẽ rất khó để nhớ hết toàn bộ đống code kể trên.
    Ngoài ra, tớ không chắc bất cứ ai muốn đọc code MIPS mà không có comment từng dòng cả. Đơn giản là rất tốn thời gian để nhớ và hiểu người viết đang làm gì, kể cả là những implementation đơn giản nhất.
  • Khi viết thủ tục, luôn luôn backup tất cả các thanh ghi được sử dụng trong thủ tục trước khi thực hiên vào stack (cậu có thanh ghi $sp để đánh dấu vị trí của stack), kể cả thanh ghi $ra (sẽ có lúc cậu cần gọi tới các thủ tục khác trong thủ tục hiện tại), và rollback lại ngay trước lệnh jr.
    Nếu cậu không làm vậy, cậu sẽ sớm gặp vấn đề khi cập nhật giá trị thanh ghi đã được sử dụng ở đâu đó rồi (số lượng thanh ghi của cậu là hữu hạn mà).
    Cậu cũng không nên sử dụng sp để implement stack. Cậu nên tạo một vùng space mới, rồi lưu giá trị vào đó.
  • Luôn sử dụng thanh ghi a để đưa argument đầu vào cho thủ tục, thanh ghi s để lưu trữ các biến quan trọng dùng trong suốt thủ tục, thanh ghi t để lưu trữ các biến tạm, thanh ghi v để lưu trữ giá trị trả về.
    Đó là convention thường được sử dụng trong MIPS.

Hope it helps!

3 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?