在使用跳转和链接之前,如何正确地将返回地址保存在mips中,以确保我回到原来的位置

问题描述 投票:0回答:1

从跳转和链接返回时,我似乎没有返回到正确的地址,我不知道为什么

    .data
    fprompt: .asciiz "Jep numrin e antarve te vektorit (max 5): "
    sprompt: .asciiz "\nShtyp elementet nje nga nje: \n"

.text
.globl main

populloVektorin:
    addi $sp, $sp, -12   # Create space for local variables on the stack
    sw $s0, 0($sp)
    sw $s1, 4($sp)
    sw $s3, 8($sp)       # Save $s0, $s1, and $s3 on the stack
    move $s0, $a0       # Pointer to the array
    prompt:
        li $v0, 4            # Print string
        la $a0, fprompt      # Load string address
        syscall
        li $v0, 5            # Read integer
        syscall             # Read integer
        move $s1, $v0        # Save the number of array elements
        bgt $s1, 5, prompt  # If the number of elements is greater than 5, return
        li $v0, 4            # Print string
        la $a0, sprompt      # Load string address
        syscall             # Print string
        li $t0, 0           # Counter

    inputElement:
        blt $t0, $s1, loop1
        j loopExit1
    loop1:
        li $v0, 5
        syscall
        move $t1, $v0
        mul $t2, $t0, 4  # Calculate the offset (element_size * index)
        add $t3, $s0, $t2  # Calculate the address by adding the offset to the base address
        sw $t1, 0($t3)       # Store the element in the array
        addi $t0, $t0, 1
        j inputElement

    loopExit1:
        move $v0, $s1  # Return the number of elements
        lw $s0, 0($sp)  # Restore $s0
        lw $s1, 4($sp)  # Restore $s1
        lw $s3, 8($sp)  # Restore $s3
        addi $sp, $sp, 12  # Restore the stack pointer
        jr $ra

unazaKalimit:
    addi $sp, $sp, -24   # Create space for local variables on the stack
    sw $s0, 0($sp)
    sw $s1, 4($sp)
    sw $s2, 8($sp)       # Save $s0, $s1, and $s3 on the stack
    sw $s3, 12($sp)
    sw $s4, 16($sp)
    sw $ra, 20($sp)
     
    li $s0, 0 # s0 iterator
    move $s1, $a0 # s1 is the pointer to the array
    move $s2, $a1 # s2 is the number of array elements
    addi $t1, $s2, -1 # t1 is the last index
    for1:
        blt $s0, $t1, loop3  # if i < n-1
        j loopExit3
    loop3:
        mul $t4, $s0, 4  # t4 is the index of the current element
        add $t5, $s1, $t4  # Calculate the address by adding the offset to the base address
        lw $s3, 0($t5)  # Load the element using the calculated address
        move $s4, $s0  # current index
        move $a0, $s0
        move $a1, $s1
        move $a2, $s2
        # move $a0, $ra
        # li $v0, 1
        # syscall
        
        jal unazaVlerave
        
         
        lw $t5, 0($t5)  # Load the element using the calculated address
        sw $t5, 0($t5)  # Store the element in the array using the calculated address
        addi $s0, $s0, 1
        j for1

    loopExit3:
        lw $s0, 0($sp)  # Restore $s0
        lw $s1, 4($sp)  # Restore $s1
        lw $s2, 8($sp)  # Restore $s2
        lw $s3, 12($sp)  # Restore $s3
        lw $s4, 16($sp)  # Restore $s4
        lw $ra, 20($sp)
        addi $sp, $sp, 20  # Restore the stack pointer
        jr $ra

unazaVlerave:


    addi $sp, $sp, -12   # Create space for local variables on the stack
    sw $s0, 0($sp)
    sw $s1, 4($sp)
    sw $s2, 8($sp)
    move $s0, $a0  # s0 is the iterator
    move $s1, $a1  # s1 is the pointer to the array
    move $s2, $a2  # s2 is the number of array elements
    
    for:
        addi $s0, $s0, 1
        blt $s0, $s2, loop2
        loop2Exit:
        lw $s0, 0($sp)  # Restore $s0
        lw $s1, 4($sp)  # Restore $s1
        lw $s2, 8($sp)  # Restore $s2
        addi $sp, $sp, 12  # Restore the stack pointer
        move $a0, $ra
        li $v0, 1
        syscall
        
        jr $ra
    loop2:
        mul $t3, $s0, 4  # Calculate the offset (element_size * index)
        add $t4, $s1, $t3  # Calculate the address by adding the offset to the base address
        lw $s3, 0($t4)  # Load the element using the calculated address
        move $s4, $s0  # current index


        
        j for
    
       

main:
    li $v0, 9
    li $a0, 20
    syscall
    move $s0, $v0
    move $a0, $s0
    jal populloVektorin
    move $s1, $v0
    move $a0, $s0
    move $a1, $s1
    
    jal unazaKalimit
    

    li $v0, 10
    syscall

这是完整的代码,调试此代码后,我发现在“for:”标签中使用跳转返回后,它不再带我回到调用跳转和链接的“unazaKalimit:”,而是抛出有关 bad 的异常记忆力。

这是选择排序在MIPS指令集中的实现

assembly mips mips32
1个回答
0
投票

只是一个简单的拼写错误,尽管可以通过阅读代码或在调试器中单步执行来找到。

函数

unazaKalimit
在进入时分配24字节的堆栈,而在退出时仅释放20字节。

这将使堆栈不平衡,并给调用者带来问题,因为他们在恢复时尝试使用自己的堆栈空间。

© www.soinside.com 2019 - 2024. All rights reserved.