If statement 跳转到各种函数MIPS
所以我是MIPS新手,我想实现简单的模算术函数。我不明白为什么程序没有根据代码中的跳转语句跳转。任何帮助都将不胜感激If statement 跳转到各种函数MIPS,if-statement,assembly,mips,If Statement,Assembly,Mips,所以我是MIPS新手,我想实现简单的模算术函数。我不明白为什么程序没有根据代码中的跳转语句跳转。任何帮助都将不胜感激 .data text_enquiry : .asciiz "Enter operation code (1-add, 2-subtract, 3-multiply, 4-exponentiation, 5-inversion, 6-exit): " text_a : .asciiz "Enter a: " text_b :
.data
text_enquiry : .asciiz "Enter operation code (1-add, 2-subtract, 3-multiply, 4-exponentiation, 5-inversion, 6-exit): "
text_a : .asciiz "Enter a: "
text_b : .asciiz "Enter b: "
text_m : .asciiz "Enter m: "
text_result : .asciiz "Result = "
new_line : .asciiz "\n"
.text
main:
## t0 = code, t1 = a, t2 = b, t3 = m
#print operation message
la $a0, text_enquiry
li $v0, 4
syscall
#read code
li $v0, 5
syscall
move $t0, $v0
#if code == 6
beq $t0, 6, exit
j rest
exit:
li $v0, 10
syscall
#else, continue procedure
#print 'a, b, m' messages and read them
rest:
la $a1, text_a
li $v0, 4
syscall
li $v0, 5
syscall
move $t1, $v0
la $a1, text_b
li $v0, 4
syscall
li $v0, 5
syscall
move $t2, $v0
la $a1, text_m
li $v0, 4
syscall
li $v0, 5
syscall
move $t3, $v0
j mod
## t0 = code, t1 = a, t2 = b, t3 = m, t4 = un-modded result, t5 = modded result, t6 =
mod:
beq $t0, 1, func_add
beq $t0, 2, func_sub
beq $t0, 3, func_mul
# beq $t0, 4, func_exp
func_add:
add $t4, $t1, $t2
div $t4, $t3
mfhi $t5
#print accordingly
la $a3, text_result
li $v0, 4
syscall
move $a3, $t5
li $v0, 1
syscall
la $a3, new_line
li $v0, 4
syscall
j main
func_sub:
sub $t4, $t1, $t2
div $t4, $t3
mfhi $t5
#print accordingly
la $a3, text_result
li $v0, 4
syscall
move $a3, $t5
li $v0, 1
syscall
j main
func_mul:
mult $t1, $t2
mflo $t4
div $t4, $t3
mfhi $t5
#print accordingly
la $a3, text_result
li $v0, 4
syscall
move $a3, $t5
li $v0, 1
syscall
j main
如您所见,当代码为“6”时,代码工作正常,但对任何其他代码值都不起作用
我不明白为什么程序没有根据代码中的跳转语句跳转。任何帮助都将不胜感激
.data
text_enquiry : .asciiz "Enter operation code (1-add, 2-subtract, 3-multiply, 4-exponentiation, 5-inversion, 6-exit): "
text_a : .asciiz "Enter a: "
text_b : .asciiz "Enter b: "
text_m : .asciiz "Enter m: "
text_result : .asciiz "Result = "
new_line : .asciiz "\n"
.text
main:
## t0 = code, t1 = a, t2 = b, t3 = m
#print operation message
la $a0, text_enquiry
li $v0, 4
syscall
#read code
li $v0, 5
syscall
move $t0, $v0
#if code == 6
beq $t0, 6, exit
j rest
exit:
li $v0, 10
syscall
#else, continue procedure
#print 'a, b, m' messages and read them
rest:
la $a1, text_a
li $v0, 4
syscall
li $v0, 5
syscall
move $t1, $v0
la $a1, text_b
li $v0, 4
syscall
li $v0, 5
syscall
move $t2, $v0
la $a1, text_m
li $v0, 4
syscall
li $v0, 5
syscall
move $t3, $v0
j mod
## t0 = code, t1 = a, t2 = b, t3 = m, t4 = un-modded result, t5 = modded result, t6 =
mod:
beq $t0, 1, func_add
beq $t0, 2, func_sub
beq $t0, 3, func_mul
# beq $t0, 4, func_exp
func_add:
add $t4, $t1, $t2
div $t4, $t3
mfhi $t5
#print accordingly
la $a3, text_result
li $v0, 4
syscall
move $a3, $t5
li $v0, 1
syscall
la $a3, new_line
li $v0, 4
syscall
j main
func_sub:
sub $t4, $t1, $t2
div $t4, $t3
mfhi $t5
#print accordingly
la $a3, text_result
li $v0, 4
syscall
move $a3, $t5
li $v0, 1
syscall
j main
func_mul:
mult $t1, $t2
mflo $t4
div $t4, $t3
mfhi $t5
#print accordingly
la $a3, text_result
li $v0, 4
syscall
move $a3, $t5
li $v0, 1
syscall
j main
您的程序正在根据输入进行跳转
您无法看到的是它真正的功能以及进一步文本输出失败的原因,您无法看到,因为您甚至没有查看(在调试器中,单步执行每条指令)
请看一看,您会清楚地看到,例如对于输入“3”,代码将在标签rest:
之后到达指令,因此分支是正确的
后来的代码没有达到您的预期,因为它没有打印其他帮助程序提示,因为它使用错误的参数调用syscall
(代码使用字符串地址设置a1
,而不是a0
,并且在a0
中仍然是原始操作提示地址),但它是按计划执行的
通常,仅通过检查输入/输出来决定汇编代码的正确性是非常糟糕的做法,因为您经常“偶然”获得正确的输出,而代码已经在做一些与计划不同的事情,如果您继续扩展代码,或者使用不同的输入,这可能会在以后影响您
为了确定汇编代码是否正确,您应该在编写代码时花相当多的时间在调试器中,验证不同的输入,并思考代码如何工作,以及是否真的按照计划/假设工作——按指令编写
最终的代码应该只包含您确切知道它们在做什么的指令,以及它们为什么是代码的一部分,以及它们为什么被放置在它们所在的位置。如果任何东西在你没有真正理解它的情况下“偶然”工作,你必须修复它(或者通过理解它是如何工作的,或者通过以你理解它是如何工作的方式重写它),它仍然是bug,即使输出是正确的
我不明白为什么程序没有根据代码中的跳转语句跳转。任何帮助都将不胜感激
.data
text_enquiry : .asciiz "Enter operation code (1-add, 2-subtract, 3-multiply, 4-exponentiation, 5-inversion, 6-exit): "
text_a : .asciiz "Enter a: "
text_b : .asciiz "Enter b: "
text_m : .asciiz "Enter m: "
text_result : .asciiz "Result = "
new_line : .asciiz "\n"
.text
main:
## t0 = code, t1 = a, t2 = b, t3 = m
#print operation message
la $a0, text_enquiry
li $v0, 4
syscall
#read code
li $v0, 5
syscall
move $t0, $v0
#if code == 6
beq $t0, 6, exit
j rest
exit:
li $v0, 10
syscall
#else, continue procedure
#print 'a, b, m' messages and read them
rest:
la $a1, text_a
li $v0, 4
syscall
li $v0, 5
syscall
move $t1, $v0
la $a1, text_b
li $v0, 4
syscall
li $v0, 5
syscall
move $t2, $v0
la $a1, text_m
li $v0, 4
syscall
li $v0, 5
syscall
move $t3, $v0
j mod
## t0 = code, t1 = a, t2 = b, t3 = m, t4 = un-modded result, t5 = modded result, t6 =
mod:
beq $t0, 1, func_add
beq $t0, 2, func_sub
beq $t0, 3, func_mul
# beq $t0, 4, func_exp
func_add:
add $t4, $t1, $t2
div $t4, $t3
mfhi $t5
#print accordingly
la $a3, text_result
li $v0, 4
syscall
move $a3, $t5
li $v0, 1
syscall
la $a3, new_line
li $v0, 4
syscall
j main
func_sub:
sub $t4, $t1, $t2
div $t4, $t3
mfhi $t5
#print accordingly
la $a3, text_result
li $v0, 4
syscall
move $a3, $t5
li $v0, 1
syscall
j main
func_mul:
mult $t1, $t2
mflo $t4
div $t4, $t3
mfhi $t5
#print accordingly
la $a3, text_result
li $v0, 4
syscall
move $a3, $t5
li $v0, 1
syscall
j main
您的程序正在根据输入进行跳转
您无法看到的是它真正的功能以及进一步文本输出失败的原因,您无法看到,因为您甚至没有查看(在调试器中,单步执行每条指令)
请看一看,您会清楚地看到,例如对于输入“3”,代码将在标签rest:
之后到达指令,因此分支是正确的
后来的代码没有达到您的预期,因为它没有打印其他帮助程序提示,因为它使用错误的参数调用syscall
(代码使用字符串地址设置a1
,而不是a0
,并且在a0
中仍然是原始操作提示地址),但它是按计划执行的
通常,仅通过检查输入/输出来决定汇编代码的正确性是非常糟糕的做法,因为您经常“偶然”获得正确的输出,而代码已经在做一些与计划不同的事情,如果您继续扩展代码,或者使用不同的输入,这可能会在以后影响您
为了确定汇编代码是否正确,您应该在编写代码时花相当多的时间在调试器中,验证不同的输入,并思考代码如何工作,以及是否真的按照计划/假设工作——按指令编写
最终的代码应该只包含您确切知道它们在做什么的指令,以及它们为什么是代码的一部分,以及它们为什么被放置在它们所在的位置。如果您没有真正理解任何东西“偶然”工作,您必须修复它(通过理解它是如何工作的,或者通过以您理解它是如何工作的方式重写它),即使输出是正确的,它仍然是错误。当您说代码“工作不正常”时,请更具体一些。你说了它不做什么,但没有说它做什么。你使用什么环境来运行它?从退出系统调用来看,我猜是SPIM系列模拟器或火星。这些可以在选项中配置,以模拟延迟分支(像真正的CPU一样)或不模拟延迟分支(对于新手来说更容易理解,但不像真正的MIPS CPU)。此外,这些模拟器还包括调试器,因此您可以轻松地自己尝试,每一条指令都会发生什么,慢慢地跳过它们,检查寄存器中的所有值以及您的假设与前一条指令的实际操作。(我没有费心将您的代码复制到simulator+自己尝试)但我认为第一个分支应该在延迟分支关闭(延迟分支“打开”时工作(6 vs其他值),我实际上不确定延迟分支包含另一条
j
指令时会发生什么,从未在simulator中尝试过,我不是MIPS专家),所以不清楚什么不适合你。我相信标签rest:
是在非6输入的情况下达到的。@Ped7g“如果分支、跳转、ERET、DERET或WAIT指令被放置在分支或跳转的延迟槽中,则处理器操作是不可预测的。”@Ped7g否,即使是第一个分支也不起作用。它会继续在主部分打印操作消息,而不会进入任何其他部分(如rest
,mod
,等等)。当您说代码“工作不正常”时,请更具体一些。你说了它不做什么,但没有说它做什么。你使用什么环境来运行它?从退出系统调用来看,我猜是SPIM系列模拟器或火星。这些可以在选项中配置,以模拟延迟分支(如