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将周围的值更新为数字(如果它们与炸弹接触)


只有当fillAroundArray知道空格是用数字3编码时,两个循环才会重复相同的次数。要验证

 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语句的用法告诉汇编程序需要保留这些寄存器。它们在函数序言和结束语代码中自动保存和恢复到堆栈上。