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