Assembly 汇编中的递归问题:编码扫雷舰
所以现在我正试图为一个类编写“扫雷舰”。我被卡住的部分是在用户单击空白磁贴后尝试更新所有网格 不幸的是,每当我试图运行我的代码时,它就会崩溃。有人能帮忙吗Assembly 汇编中的递归问题:编码扫雷舰,assembly,recursion,x86,minesweeper,Assembly,Recursion,X86,Minesweeper,所以现在我正试图为一个类编写“扫雷舰”。我被卡住的部分是在用户单击空白磁贴后尝试更新所有网格 不幸的是,每当我试图运行我的代码时,它就会崩溃。有人能帮忙吗 whitespaceClick PROC uses eax ebx ecx esi edi call convertXYval mov GridValues[eax], 250 call updateSurroundings mov edi, 0 call clearAroundArray call fillAroundArray cmp
whitespaceClick PROC uses eax ebx ecx esi edi
call convertXYval
mov GridValues[eax], 250
call updateSurroundings
mov edi, 0
call clearAroundArray
call fillAroundArray
cmp edi, 0 ;if no spaces around it
je done
mov ecx, 8
mov esi, 0
store:
cmp aroundArray[esi], 3
jne skp
mov bh, aroundArrayX[esi]
mov bl, aroundArrayY[esi]
push bx
skp:
inc esi
loop store
mov eax, 0
mov ecx, edi
update:
pop ax
mov X, ah
mov Y, al
call whitespaceClick
loop update
Done:
ret
whitespaceClick ENDP
注:
- X和Y是字节类型的变量,用于跟踪当前位置
- convertXYval是一个将x、y值转换为与数组中的位置相对应的单个值的过程
- fillAroundArray将用值(0,1,2,3)填充一个8元素数组,并返回edi中当前位置周围的空格数
- whitespaceClick将周围的值更新为数字(如果它们与炸弹接触)
whitespaceClick PROC uses eax ebx ecx esi edi
是否在您的过程中使用。。。自动意味着这些寄存器被保留?如果没有,则需要围绕递归调用保存/恢复循环计数器的值
mov Y, al
push ecx
call whitespaceClick
pop ecx
loop update
在16位代码中,使用ECX作为小循环计数器是愚蠢的。因此我得出结论,这是32位代码,然后我建议将
push bx
和pop ax
更改为dword变体。这将在这些递归调用中保持dword对齐的堆栈。学习使用调试器。非常可疑的是,有两个循环具有不同的迭代计数,第一个循环推送值,第二个循环弹出。还要注释您的代码,特别是如果您需要其他人的帮助。另请参见。我对这两个循环有一个合理的理由。第一个循环的目的是找到包含空格的相邻xy值并将其存储。第二个循环一次提取一个值,将x和y设置为它们,然后调用可能是,但这两个循环是否会处理相同数量的项并不明显,如果堆栈变得不平衡,就会导致崩溃。第一个循环运行8次,但仅有条件地推送一个值,第二个循环运行edi
次,无论edi
是什么。另外,不清楚为什么不能在第一个循环中调用whitespaceClick而不在堆栈中存储内容。正如我所说,请(明智地)注释代码并使用调试器。@Jester edi包含相邻的空格数,我在笔记中提到了这一点。这两个循环将迭代相同的次数,如果您提供。我认为在没有看到周围代码的情况下回答这个问题是不可能的。产生问题的最小完整运行程序是理想的。MASM/TASM汇编中PROC语句的用法告诉汇编程序需要保留这些寄存器。它们在函数序言和结束语代码中自动保存和恢复到堆栈上。