遍历9个格子winmine!StepBlock和遍历8个格子winmine!StepBox的对决
第一部分:windbg调试记录。
0: kd> g
Breakpoint 10 hit
winmine!DoButton1Up:
001b:0100390e a130510001 mov eax,dword ptr [winmine!xCur (01005130)]
0: kd> kc
#
00 winmine!DoButton1Up
01 winmine!MainWndProc
02 USER32!InternalCallWinProc
03 USER32!UserCallWinProcCheckWow
04 USER32!DispatchMessageWorker
05 USER32!DispatchMessageW
06 winmine!WinMain
07 winmine!WinMainCRTStartup
08 kernel32!BaseProcessStart
0: kd> g
Breakpoint 12 hit
winmine!StepBox:
001b:010031aa 55 push ebp
1: kd> u
winmine!StepBox [d:\srv03rtm\shell\osshell\ep\winmine\rtns.c @ 254]:
010031aa 55 push ebp
010031ab 8bec mov ebp,esp
010031ad 53 push ebx
010031ae ff750c push dword ptr [ebp+0Ch]
010031b1 33db xor ebx,ebx
010031b3 ff7508 push dword ptr [ebp+8]
010031b6 43 inc ebx
010031b7 891db8570001 mov dword ptr [winmine!iStepMac (010057b8)],ebx
1: kd> pc
winmine!StepBox+0x13:
001b:010031bd e86cffffff call winmine!StepXY (0100312e)
1: kd> t
Breakpoint 15 hit
winmine!StepXY:
001b:0100312e 55 push ebp
1: kd> dv
x = 0n1
y = 0n6
cBombs = 0n6
1: kd> kc
#
00 winmine!StepXY
01 winmine!StepBox
02 winmine!StepBlock
03 winmine!DoButton1Up
04 winmine!MainWndProc
05 USER32!InternalCallWinProc
06 USER32!UserCallWinProcCheckWow
07 USER32!DispatchMessageWorker
08 USER32!DispatchMessageW
09 winmine!WinMain
0a winmine!WinMainCRTStartup
0b kernel32!BaseProcessStart
1: kd> g
Breakpoint 18 hit
winmine!DisplayBlk:
001b:01002744 55 push ebp
1: kd> gu
winmine!StepXY+0x4a:
001b:01003178 837d0c00 cmp dword ptr [ebp+0Ch],0
0: kd> dv
x = 0n1
y = 0n1
cBombs = 0n1
0: kd> h
^ Syntax error in 'h'
0: kd> g
Breakpoint 12 hit
winmine!StepBox:
001b:010031aa 55 push ebp
0: kd> dv
x = 0n2
y = 0n6
0: kd> kc
#
00 winmine!StepBox
01 winmine!StepBlock
02 winmine!DoButton1Up
03 winmine!MainWndProc
04 USER32!InternalCallWinProc
05 USER32!UserCallWinProcCheckWow
06 USER32!DispatchMessageWorker
07 USER32!DispatchMessageW
08 winmine!WinMain
09 winmine!WinMainCRTStartup
0a kernel32!BaseProcessStart
0: kd> y
^ Syntax error in 'y'
0: kd> u
winmine!StepBox [d:\srv03rtm\shell\osshell\ep\winmine\rtns.c @ 254]:
010031aa 55 push ebp
010031ab 8bec mov ebp,esp
010031ad 53 push ebx
010031ae ff750c push dword ptr [ebp+0Ch]
010031b1 33db xor ebx,ebx
010031b3 ff7508 push dword ptr [ebp+8]
010031b6 43 inc ebx
010031b7 891db8570001 mov dword ptr [winmine!iStepMac (010057b8)],ebx
0: kd> g
Breakpoint 15 hit
winmine!StepXY:
001b:0100312e 55 push ebp
0: kd> dv
x = 0n2
y = 0n6
cBombs = 0n6
0: kd> g
Breakpoint 12 hit
winmine!StepBox:
001b:010031aa 55 push ebp
0: kd> dv
x = 0n3
y = 0n6
0: kd> p
winmine!StepBox+0x4:
001b:010031ae ff750c push dword ptr [ebp+0Ch]
0: kd> p
Breakpoint 15 hit
winmine!StepXY:
001b:0100312e 55 push ebp
0: kd> dv
x = 0n3
y = 0n6
cBombs = 0n6
0: kd> g
Breakpoint 12 hit
winmine!StepBox:
001b:010031aa 55 push ebp
0: kd> dv
x = 0n1
y = 0n7
0: kd> p
winmine!StepBox+0x4:
001b:010031ae ff750c push dword ptr [ebp+0Ch]
0: kd> p
Breakpoint 15 hit
winmine!StepXY:
001b:0100312e 55 push ebp
0: kd> dv
x = 0n1
y = 0n7
cBombs = 0n7
0: kd> g
Breakpoint 18 hit
winmine!DisplayBlk:
001b:01002744 55 push ebp
0: kd> gu
winmine!StepXY+0x4a:
001b:01003178 837d0c00 cmp dword ptr [ebp+0Ch],0
0: kd> dv
x = 0n1
y = 0n0
cBombs = 0n0
0: kd> gu
winmine!StepBox+0x18:
001b:010031c2 391db8570001 cmp dword ptr [winmine!iStepMac (010057b8)],ebx
0: kd> u
winmine!StepBox+0x18 [d:\srv03rtm\shell\osshell\ep\winmine\rtns.c @ 262]:
010031c2 391db8570001 cmp dword ptr [winmine!iStepMac (010057b8)],ebx
010031c8 7470 je winmine!StepBox+0x90 (0100323a)
010031ca 56 push esi
010031cb 57 push edi
010031cc 8b349de0570001 mov esi,dword ptr winmine!rgStepY (010057e0)[ebx*4]
010031d3 8b3c9dc0510001 mov edi,dword ptr winmine!rgStepX (010051c0)[ebx*4]
010031da 4e dec esi
010031db 8d47ff lea eax,[edi-1]
0: kd> p
winmine!StepBox+0x22:
001b:010031cc 8b349de0570001 mov esi,dword ptr winmine!rgStepY (010057e0)[ebx*4]
0: kd> dv
x = 0n1
y = 0n7
0: kd> d winmine!rgStepX[1]
0: kd> dt winmine!rgStepX[1]
[1] 0n1
0: kd> dt winmine!rgStepY[1]
[1] 0n7
0: kd> g
Breakpoint 15 hit
winmine!StepXY:
001b:0100312e 55 push ebp
0: kd> dv
x = 0n0
y = 0n6
cBombs = 0n6
0: kd> g
Breakpoint 15 hit
winmine!StepXY:
001b:0100312e 55 push ebp
0: kd> dv
x = 0n1
y = 0n6
cBombs = 0n6
0: kd> g
Breakpoint 15 hit
winmine!StepXY:
001b:0100312e 55 push ebp
0: kd> fv
Couldn't resolve error at 'v'
0: kd> dv
x = 0n2
y = 0n6
cBombs = 0n6
0: kd> g
Breakpoint 15 hit
winmine!StepXY:
001b:0100312e 55 push ebp
0: kd> dv
x = 0n0
y = 0n7
cBombs = 0n7
0: kd> g
Breakpoint 15 hit
winmine!StepXY:
001b:0100312e 55 push ebp
0: kd> dv
x = 0n2
y = 0n7
cBombs = 0n7
0: kd> g
Breakpoint 15 hit
winmine!StepXY:
001b:0100312e 55 push ebp
0: kd> dv
x = 0n0
y = 0n8
cBombs = 0n8
0: kd> g
Breakpoint 15 hit
winmine!StepXY:
001b:0100312e 55 push ebp
0: kd> dv
x = 0n1
y = 0n8
cBombs = 0n8
0: kd> g
Breakpoint 18 hit
winmine!DisplayBlk:
001b:01002744 55 push ebp
0: kd> dv
x = 0n1
y = 0n8
0: kd> g
Breakpoint 15 hit
winmine!StepXY:
001b:0100312e 55 push ebp
0: kd> dv
x = 0n2
y = 0n8
cBombs = 0n8
0: kd> g
Breakpoint 12 hit
winmine!StepBox:
001b:010031aa 55 push ebp
0: kd> dv
x = 0n2
y = 0n7
0: kd> kc
#
00 winmine!StepBox
01 winmine!StepBlock
02 winmine!DoButton1Up
03 winmine!MainWndProc
04 USER32!InternalCallWinProc
05 USER32!UserCallWinProcCheckWow
06 USER32!DispatchMessageWorker
07 USER32!DispatchMessageW
08 winmine!WinMain
09 winmine!WinMainCRTStartup
0a kernel32!BaseProcessStart
0: kd> g
Breakpoint 15 hit
winmine!StepXY:
001b:0100312e 55 push ebp
0: kd> dv
x = 0n2
y = 0n7
cBombs = 0n7
0: kd> g
Breakpoint 12 hit
winmine!StepBox:
001b:010031aa 55 push ebp
0: kd> dv
x = 0n3
y = 0n7
0: kd> g
Breakpoint 15 hit
winmine!StepXY:
001b:0100312e 55 push ebp
0: kd> dv
x = 0n3
y = 0n7
cBombs = 0n7
0: kd> g
Breakpoint 12 hit
winmine!StepBox:
001b:010031aa 55 push ebp
0: kd> dv
x = 0n1
y = 0n8
0: kd> g
Breakpoint 15 hit
winmine!StepXY:
001b:0100312e 55 push ebp
0: kd> dv
x = 0n1
y = 0n8
cBombs = 0n8
0: kd> g
Breakpoint 12 hit
winmine!StepBox:
001b:010031aa 55 push ebp
0: kd> dv
x = 0n2
y = 0n8
0: kd> g
Breakpoint 15 hit
winmine!StepXY:
001b:0100312e 55 push ebp
0: kd> dv
x = 0n2
y = 0n8
cBombs = 0n8
0: kd> g
Breakpoint 12 hit
winmine!StepBox:
001b:010031aa 55 push ebp
0: kd> dv
x = 0n3
y = 0n8
0: kd> g
Breakpoint 15 hit
winmine!StepXY:
001b:0100312e 55 push ebp
0: kd> dv
x = 0n3
y = 0n8
cBombs = 0n8
0: kd> g
Breakpoint 14 hit
winmine!DrawButton:
001b:010029e2 55 push ebp
第二部分:解释和代码
++i 返回加1后的值,碰到X1Y7cBombs等于0,
所以++iStepMac等于2
if (++iStepCur != iStepMac)
成立
所以会遍历8个格子。
其他情况iStepMac等于1,++iStepCur等于1,
直接返回了。
所以会到X1Y7的时候会遍历8个格子。
X0Y6 X1Y6 X2Y6
X0Y7 X3Y7
X0Y8 X1Y8 X2Y8
返回,继续遍历第五个格子X2Y7
/****** S T E P X Y ******/
VOID StepXY(INT x, INT y)
{
INT cBombs;
INT iBlk = (y<<5) + x;
BLK blk = rgBlk[iBlk];
if ( (blk & MaskVisit) ||
((blk &= MaskData) == iBlkMax) ||
(blk == iBlkBombUp) )
return;
cBoxVisit++;
rgBlk[iBlk] = (CHAR) (MaskVisit | (cBombs = CountBombs(x,y)));
//
// SetDIBitsToDevice(hDCCapture,
// (x<<4)+(dxGridOff-dxBlk), (y<<4)+(dyGridOff-dyBlk),
// dxBlk, dyBlk, 0, 0, 0, dyBlk,
// lpDibBlks + rgDibOff[cBombs],
// (LPBITMAPINFO) lpDibBlks, DIB_RGB_COLORS);
//
DisplayBlk(x,y);
if (cBombs != 0)
return;
rgStepX[iStepMac] = x;
rgStepY[iStepMac] = y;
if (++iStepMac == iStepMax)
iStepMac = 0;
}
/****** S T E P B O X ******/
VOID StepBox(INT x, INT y)
{
INT iStepCur = 0;
iStepMac = 1;
StepXY(x,y);
if (++iStepCur != iStepMac)
while (iStepCur != iStepMac)
{
x = rgStepX[iStepCur];
y = rgStepY[iStepCur];
StepXY(x-1, --y);
StepXY(x, y);
StepXY(x+1, y);
StepXY(x-1, ++y);
StepXY(x+1, y);
StepXY(x-1, ++y);
StepXY(x, y);
StepXY(x+1, y);
if (++iStepCur == iStepMax)
iStepCur = 0;
}
}
/****** S T E P B L O C K ******/
/* Step in a block around a single square */
VOID StepBlock(INT xCenter, INT yCenter)
{
REGISTER INT x;
REGISTER INT y;
BOOL fGameOver = fFalse;
if ( (!fVISIT(xCenter,yCenter))
/* || fGUESSBOMB(xCenter,yCenter) */
|| (iBLK(xCenter,yCenter) != CountMarks(xCenter,yCenter)) )
{
/* not a safe thing to do */
TrackMouse(-2, -2); /* pop up the blocks */
return;
}
for(y=yCenter-1; y<=yCenter+1; y++)
for(x=xCenter-1; x<=xCenter+1; x++)
{
if (!fGUESSBOMB(x,y) && fISBOMB(x,y))
{
fGameOver = fTrue;
ChangeBlk(x, y, MaskVisit | iBlkExplode);
}
else
StepBox(x,y);
}
if (fGameOver)
GameOver(fLose);
else if (fCheckWin())
GameOver(fWin);
}
第三部分:关键数组
0: kd> db winmine!rgBlk
01005360 10 10 10 10 10 10 10 10-10 10 10 0f 0f 0f 0f 0f ................
01005370 0f 0f 0f 0f 0f 0f 0f 0f-0f 0f 0f 0f 0f 0f 0f 0f ................
01005380 10 0f 0f 8f 41 40 40 40-40 40 10 0f 0f 0f 0f 0f ....A@@@@@......
01005390 0f 0f 0f 0f 0f 0f 0f 0f-0f 0f 0f 0f 0f 0f 0f 0f ................
010053a0 10 0f 8f 0f 41 41 41 41-40 40 10 0f 0f 0f 0f 0f ....AAAA@@......
010053b0 0f 0f 0f 0f 0f 0f 0f 0f-0f 0f 0f 0f 0f 0f 0f 0f ................
010053c0 10 0f 0f 0f 41 41 8e 41-40 40 10 0f 0f 0f 0f 0f ....AA.A@@......
010053d0 0f 0f 0f 0f 0f 0f 0f 0f-0f 0f 0f 0f 0f 0f 0f 0f ................
0: kd> db
010053e0 10 8f 0f 8f 42 41 41 41-40 40 10 0f 0f 0f 0f 0f ....BAAA@@......
010053f0 0f 0f 0f 0f 0f 0f 0f 0f-0f 0f 0f 0f 0f 0f 0f 0f ................
01005400 10 0f 8f 8f 43 40 40 40-40 40 10 0f 0f 0f 0f 0f ....C@@@@@......
01005410 0f 0f 0f 0f 0f 0f 0f 0f-0f 0f 0f 0f 0f 0f 0f 0f ................
01005420 10 41 43 8e 42 40 40 40-40 40 10 0f 0f 0f 0f 0f .AC.B@@@@@...... 第六行
01005430 0f 0f 0f 0f 0f 0f 0f 0f-0f 0f 0f 0f 0f 0f 0f 0f ................
01005440 10 40 41 41 41 40 40 40-40 40 10 0f 0f 0f 0f 0f .@AAA@@@@@...... 第七行
01005450 0f 0f 0f 0f 0f 0f 0f 0f-0f 0f 0f 0f 0f 0f 0f 0f ................
0: kd> db
01005460 10 41 41 40 41 41 41 40-40 40 10 0f 0f 0f 0f 0f .AA@AAA@@@...... 第八行
01005470 0f 0f 0f 0f 0f 0f 0f 0f-0f 0f 0f 0f 0f 0f 0f 0f ................
01005480 10 8f 41 40 41 8f 41 40-40 40 10 0f 0f 0f 0f 0f ..A@A.A@@@...... 第九行
01005490 0f 0f 0f 0f 0f 0f 0f 0f-0f 0f 0f 0f 0f 0f 0f 0f ................
010054a0 10 10 10 10 10 10 10 10-10 10 10 0f 0f 0f 0f 0f ................
010054b0 0f 0f 0f 0f 0f 0f 0f 0f-0f 0f 0f 0f 0f 0f 0f 0f ................