我已经尝试改变了这么多的代码,但我一直得到neverending算术溢出警告或'坏地址在数据/堆栈'错误.我似乎不能得到它正确!任何见解是受欢迎的!我试图实现一个数独板,这些是这个函数的说明:给一个数独棋盘的指针,这个函数应该返回一个整数,表示棋盘中有多少个单元格已经被解出。棋盘的状态应该是未修改的。每个数独单元格总共占用10个字节。每个单元占用10个字节,整个板占用810个字节的内存。
有什么发现吗?
# a0: pointer to board
# v0: number of solved cells
count_solved_cells:
li $v0, 0 # Initialize count to 0
la $s0, board # Load the address of the board to $s0
li $t0, 81 # Initialize loop counter
count_cells_loop:
jal is_cell_solved # Check if the current cell is solved
addi $v0, $v0, 1 # Increment count regardless of cell status
addi $s0, $s0, 10 # Move to the next cell (each cell is 10 bytes)
addi $t0, $t0, -1 # Decrement loop counter
bnez $t0, count_cells_loop # If not reached the end of the board, continue the loop
jr $ra
字符串
2条答案
按热度按时间moiiocjp1#
@Reda Bourial已经指出,也许你需要在这个函数中计数是有条件的,而不是无条件的。
其他6个逻辑错误是调用约定,即与我们在C或其他语言中看不到的函数调用有关,因为编译器为我们处理了这些细节。(我们假设你的意图是遵循标准的调用约定,这是大多数教学作业的想法,因为在不首先知道标准方法和为什么使用它们的情况下,尝试调用约定偏差/优化是没有教育意义的。
在寄存器机器上调用函数是初学者最难掌握的事情之一,这并不是因为它从根本上很深或相互交织,而是因为有几个不同的规则,每个规则都很简单,但在一起需要记住很多东西,以及何时使用哪个规则。
逻辑错误不一定会导致无限循环或程序崩溃,因为周围的代码(调用者和被调用者)不会测试这些逻辑是否错误。由于您没有显示任何代码,但只有一个函数,因此我们不能说其中的一些错误。
函数调用逻辑错误有:
$ra
用于第二个目的,而不保留其值以供此函数自己的后记使用。$s0
违反了调用约定规则-没有保留和恢复,这违反了与此函数的调用者的调用约定。$v0
的使用也违反了调用约定规则,因为它期望被调用者保留这些合法的调用删除寄存器。$t0
与(3.)1.函数注解说明
$a0
是一个传入参数,但函数忽略了这个参数(可能是为了支持la
,尽管我们不认为这可能是因为缺少对被调用方实际参数的计算)。1.就像函数形参在这个函数中没有被正确使用一样,实际的参数也肯定没有为被调用方
is_cell_solved
正确设置。对于第一个错误,
$ra
寄存器预期同时保存两个不同且独立的值,但它不能这样做。但是仅在程序控制下并且绝对不是自动的程序/功能必须指示处理器如何这样做(通过将适当的指令放入机器代码指令流)。如果程序未能管理$ra
寄存器的共享,那么一些jr $ra
将不会返回到实际的调用者,而是返回到其他一些调用站点,这就是导致无限循环以及随之而来的其他溢出问题的原因。izkcnapc2#
看起来你的循环中有一个问题,不管单元格的状态如何,你都要递增计数。你应该只在单元格被求解时才递增计数。另外,你需要正确处理is_cell_solved函数的返回值。
下面是代码的修改版本:
字符串
此修改包括一个分支(not_solved),用于在单元格未求解时跳过计数的增量。确保is_cell_solved函数正确返回一个值,指示单元格是否已求解。