Assembly 为什么在循环中使用$v0寄存器会返回错误的输出?

Assembly 为什么在循环中使用$v0寄存器会返回错误的输出?,assembly,mips,qtspim,Assembly,Mips,Qtspim,以下程序 给定用户输入的下限和上限,确定该范围内的最小和最小索引 对于测试用例(下界:2上界:4),我尝试了两种不同的代码,区别标记在下面 以下代码不返回预期的输出 findMin: addi $t0, $a0, 0 # initialise $t0 (current pointer) to lower bound addi $t1, $a0, 0 # initialise minimum pointer to upper bound

以下程序

  • 给定用户输入的下限和上限,确定该范围内的最小和最小索引
  • 对于测试用例(下界:2上界:4),我尝试了两种不同的代码,区别标记在下面

    以下代码不返回预期的输出

    findMin:
    
          addi $t0, $a0, 0        # initialise $t0 (current pointer) to lower bound 
          addi $t1, $a0, 0        # initialise minimum pointer to upper bound 
          lw   $t2, 0($t1)        # initialise min (value) to the lower bound  
    
    
    Loop: slt $t4, $a1, $t0
          bne $t4, $zero, End     # branch to end if upper < lower
    
          lw, $t3, 0($t0)         # store the content of the current pointer
          slt $t4, $t3, $t2       # if current ($t3) < min ($t2), store 1 in $t4
          beq $t4, $zero, LoopEnd # if it is 0, go to LoopEnd
    
          addi $t2, $t3, 0        # store content ($t3) as minimum ($t2)
          addi $v0, $t0, 0        # store the address of min (DIFFERENCE)
    
    LoopEnd: addi $t0, $t0, 4     # increments current pointer lower bound 
             j Loop               # Jump to loop 
    
    End:     jr $ra               # return from this function
    
    
    findMin:
    addi$t0,$a0,0#将$t0(当前指针)初始化为下限
    addi$t1,$a0,0#初始化指向上限的最小指针
    lw$t2,0($t1)#将最小值(值)初始化为下限
    循环:slt$t4、$a1、$t0
    bne$t4,$零,端部#如果上限<下限,则分支到端部
    lw,$t3,0($t0)#存储当前指针的内容
    slt$t4、$t3、$t2#如果当前($t3)
    但是,以下代码确实返回预期值:

    findMin:
        addi $t0, $a0, 0  # $t0 is the pointer to the current item
        addi $t1, $a0, 0  # $t1 is the pointer to the minimum item
        lw   $t2, 0($t1)  # $t2 stores the value of minimum item
    
    loop:
        slt $t4, $a1, $t0  # check if last pointer < current pointer
        bne $t4, $zero, exit # if current pointer > last pointer, exit
        lw  $t3, 0($t0)    # $t3 stores the value of current item
        slt $t4, $t3, $t2  # if the current value is lesser than minimum value
        beq $t4, $zero, skip # if current value is not lesser, then skip
    
        addi $t1, $t0, 0   # minimum pointer = current pointer (DIFFERENCE)
        lw   $t2, 0($t1)   # $t2 stores the value of minimum item
    
    skip:
        addi $t0, $t0, 4   # move to the next item
        j loop
    exit:   
        addi $v0, $t1, 0   # $v0 stores the address of the minimum item (DIFFERENCE)
        jr $ra          # return from this function
    
    findMin:
    addi$t0,$a0,0#$t0是指向当前项的指针
    addi$t1,$a0,0#$t1是指向最小项的指针
    lw$t2,0($t1)#$t2存储最小项的值
    循环:
    slt$t4、$a1、$t0#检查最后一个指针是否<当前指针
    bne$t4$零,退出#如果当前指针>最后一个指针,退出
    lw$t3,0($t0)#$t3存储当前项的值
    slt$t4、$t3、$t2#如果当前值小于最小值
    beq$t4,$zero,跳过#如果当前值不小于,则跳过
    addi$t1,$t0,0#最小指针=当前指针(差异)
    lw$t2,0($t1)#$t2存储最小项的值
    跳过:
    addi$t0,$t0,4#转到下一项
    j环
    出口:
    addi$v0,$t1,0#$v0存储最小项的地址(差异)
    jr$ra#从此函数返回
    
    这背后的理由是什么

    以下是完整的代码(可选)

    
    #arrayFunction.asm
    .数据
    数组:。字8、2、1、6、9、7、3、5、0、4
    新建:.asciiz“\n”
    .文本
    主要内容:
    #打印数组的原始内容
    #设置参数
    #调用printArray函数
    la$a0,数组#数组的基址
    la$a1,数组中的元素数为10
    jal printArray#调用函数
    #向用户询问两个索引
    li$v0,5#读取int的系统调用代码
    系统调用
    添加$t0、$v0、$零#将输入存储在$t0中
    li$v0,5#读取int的系统调用代码
    系统调用
    添加$t1、$v0、$零#将输入存储在$t1中
    #调用findMin函数
    #设置参数
    la$a0,数组#将数组地址加载到$a0中
    la$a1,数组#将数组地址加载到$a1中
    sll$t0,$t0,2#计算下界的偏移量
    sll$t1,$t1,2#计算上界的偏移量
    添加$a0、$a0、$t0#将$a0设置为下限
    添加$a1、$a1、$t1#将$a1设置为上限
    #调用函数
    日航findMin#呼叫功能
    #打印最小项
    #将最小项目放入$t3中进行打印
    addi$t3、$t2、0#将最小项目放入$t3
    addi$t4、$v0、0#保存指向min元素的指针
    #打印后跟换行符的整数
    li$v0,1#用于打印的系统调用代码
    addi$a0、$t3、0#打印$t3
    系统调用#进行系统调用
    li$v0,4#打印字符串的系统调用代码
    洛杉矶$a0,纽尔
    系统调用#打印换行符
    #计算并打印最小项的索引
    la$a0,阵列
    低于$t3、$t4、$a0
    srl$t3、$t3、2
    #将最小索引置于$t3中进行打印
    #打印最小索引
    #打印后跟换行符的整数
    li$v0,1#用于打印的系统调用代码
    addi$a0、$t3、0#打印$t3
    系统调用#进行系统调用
    li$v0,4#打印字符串的系统调用代码
    洛杉矶$a0,纽尔
    系统调用#打印换行符
    #在main的末尾,对“exit”进行系统调用
    li$v0,10#退出系统调用代码
    系统调用#终止程序
    #######################################################################
    ###函数printArray###
    #输入:$a0中的数组地址,$a1中的元素数
    #输出:无
    #用途:打印数组元素
    #使用的寄存器:$t0、$t1、$t2、$t3
    #假设:数组元素为字大小(4字节)
    打印阵列:
    addi$t1、$a0、0#$t1是指向该项的指针
    sll$t2,$a1,2#$t2是超出最后一项的偏移量
    添加$t2、$a0、$t2#$t2指向最后一项之外
    l1:
    贝币$t1、$t2、e1
    lw$t3,0($t1)#$t3是当前项目
    li$v0,1#用于打印的系统调用代码
    要打印的addi$a0、$t3、0#整数
    syscall#打印它
    附加$t1,$t1,4
    j l1#另一个迭代
    e1:
    li$v0,4#打印字符串的系统调用代码
    洛杉矶$a0,纽尔
    系统调用#打印换行符
    jr$ra#从此函数返回
    #######################################################################
    ###学生函数findMin###
    #输入:低位数组指针在$a0,高位数组指针在$a1
    #输出:$v0包含最小项的地址
    #目的:查找并返回最小项目
    #介于$a0和$a1之间(含)
    #使用的寄存器:$t0(计数器),$t1(最大添加),$t2(最小值),$v0(最小位置),$t3(当前项)
    #假设:数组元素
    
    
    # arrayFunction.asm
           .data 
    array: .word 8, 2, 1, 6, 9, 7, 3, 5, 0, 4
    newl:  .asciiz "\n"
    
           .text
    main:
        # Print the original content of array
        # setup the parameter(s)
        # call the printArray function
        la $a0, array            # base address of array
        la $a1, 10               # number of elements in array
        jal printArray           # call function 
    
    
        # Ask the user for two indices
        li   $v0, 5             # System call code for read_int
        syscall 
        add  $t0, $v0, $zero    # store input in $t0          
    
        li   $v0, 5             # System call code for read_int
        syscall           
        add  $t1, $v0, $zero    # store input in $t1          
    
        # Call the findMin function
        # setup the parameter(s) 
        la $a0, array       # load address of array into $a0
        la $a1, array       # load address of array into $a1
        sll $t0, $t0, 2         # calculate offset of lower bound
        sll $t1, $t1, 2         # calculate offset of upper bound
        add $a0, $a0, $t0       # set $a0 to the lower bound
        add $a1, $a1, $t1       # set $a1 to the upper bound 
    
        # call the function
        jal findMin             # call function 
    
    
        # Print the min item
        # place the min item in $t3 for printing
        addi $t3, $t2, 0        # placing min item in $t3 
        addi $t4, $v0, 0        # saving the pointer to the min element
    
        # Print an integer followed by a newline
        li   $v0, 1             # system call code for print_int
        addi $a0, $t3, 0        # print $t3
        syscall                 # make system call
    
        li   $v0, 4             # system call code for print_string
        la   $a0, newl      
        syscall                 # print newline
    
        #Calculate and print the index of min item
        la  $a0, array
        sub $t3, $t4, $a0   
        srl $t3, $t3, 2 
    
        # Place the min index in $t3 for printing   
    
        # Print the min index
        # Print an integer followed by a newline
        li   $v0, 1         # system call code for print_int
        addi $a0, $t3, 0    # print $t3
        syscall             # make system call
    
        li   $v0, 4         # system call code for print_string
        la   $a0, newl      
        syscall             # print newline
    
        # End of main, make a syscall to "exit"
        li   $v0, 10        # system call code for exit
        syscall             # terminate program
    
    
    #######################################################################
    ###   Function printArray   ### 
    #Input: Array Address in $a0, Number of elements in $a1
    #Output: None
    #Purpose: Print array elements
    #Registers used: $t0, $t1, $t2, $t3
    #Assumption: Array element is word size (4-byte)
    printArray:
        addi $t1, $a0, 0    #$t1 is the pointer to the item
        sll  $t2, $a1, 2    #$t2 is the offset beyond the last item
        add  $t2, $a0, $t2  #$t2 is pointing beyond the last item
    l1: 
        beq  $t1, $t2, e1
        lw   $t3, 0($t1)    # $t3 is the current item
        li   $v0, 1         # system call code for print_int
        addi $a0, $t3, 0    # integer to print
        syscall             # print it
        addi $t1, $t1, 4
        j l1            # Another iteration
    e1:
        li   $v0, 4         # system call code for print_string
        la   $a0, newl      # 
        syscall             # print newline
        jr $ra          # return from this function
    
    
    #######################################################################
    ###   Student Function findMin   ### 
    #Input: Lower Array Pointer in $a0, Higher Array Pointer in $a1
    #Output: $v0 contains the address of min item 
    #Purpose: Find and return the minimum item 
    #              between $a0 and $a1 (inclusive)
    #Registers used: $t0 (counter), $t1 (max add), $t2 (min), $v0 (min pos), $t3 (current item)
    #Assumption: Array element is word size (4-byte), $a0 <= $a1
    findMin:
    
          addi $t0, $a0, 0        # initialise $t0 (current pointer) to lower bound 
          addi $t1, $a0, 0        # initialise minimum pointer to upper bound 
          lw   $t2, 0($t1)        # initialise min (value) to the lower bound  
    
    
    Loop: slt $t4, $a1, $t0
          bne $t4, $zero, End     # branch to end if upper < lower
    
          lw, $t3, 0($t0)         # store the content of the current pointer
          slt $t4, $t3, $t2       # if current ($t3) < min ($t2), store 1 in $t4
          beq $t4, $zero, LoopEnd # if it is 0, go to LoopEnd
    
          addi $t2, $t3, 0        # store content ($t3) as minimum ($t2)
          addi $t1, $t0, 0        # store the address of min
    
    LoopEnd: addi $t0, $t0, 4     # increments current pointer lower bound 
             j Loop               # Jump to loop 
    
    End:    addi $v0, $t1, 0       
        jr $ra                # return from this function
    
    
          addi $v0, $a0, 0        # initialise minimum pointer to upper bound 
          lw   $t2, 0($v0)        # initialise min (value) to the lower bound