轩辕春秋文化论坛 » 曹操传MOD制作交流 » 请帮忙看看以下代码哪里出了问题:


2010-3-6 06:07 武骧金星
请帮忙看看以下代码哪里出了问题:

004CE7B6    8B4D FC         MOV ECX,DWORD PTR SS:[EBP-4]
004CE7B9    8A51 01         MOV DL,BYTE PTR DS:[ECX+1]
004CE7BC    8BCA            MOV ECX,EDX
004CE7BE    6BC9 24         IMUL ECX,ECX,24
004CE7C1    81C1 502C4B00   ADD ECX,Ekd5.004B2C50
[color=Red]004CE7C7    E8 A40EF9FF     CALL Ekd5.0045F670[/color]

这段代码在CALL 45F670时会出现以下的问题:(以下是单步步过的结果)

0045F670  /$  55            PUSH EBP
0045F671  |.  8BEC          MOV EBP,ESP
0045F673  |.  51            PUSH ECX
0045F674  |.  894D FC       MOV DWORD PTR SS:[EBP-4],ECX
0045F677  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]
[color=Red][color=Red]0045F67A  |.  8B00          MOV EAX,DWORD PTR DS:[EAX][/color] //访问违规: 读取[0A94AE14][/color]
0045F67C  |.  8BE5          MOV ESP,EBP
0045F67E  |.  5D            POP EBP
0045F67F  \.  C3            RETN

请问这可能是由于什么原因?谢谢。

[color=Silver][[i] 本帖最后由 武骧金星 于 2010-3-6 06:22 编辑 [/i]][/color]

2010-3-6 07:59 godtype
在004CE7B9这里加一个断点(F2),看一下从[EBP-4]输出到ECX的值是多少。

2010-3-6 12:34 武骧金星
……真奇怪,这时ECX的值是004927F0,应该是没问题的……

可是接下去几步后ECX就变成那个违规调用的内存位置了……

[color=Silver][[i] 本帖最后由 武骧金星 于 2010-3-6 13:02 编辑 [/i]][/color]

2010-3-6 13:12 武骧金星
经过仔细研究发现:原来代码应该改成这个样子:

004CE7B6    8B4D FC         MOV ECX,DWORD PTR SS:[EBP-4]
004CE7B9    8A51 01         MOV DL,BYTE PTR DS:[ECX+1]
004CE7BC    8BCA            MOV ECX,EDX
[color=Red]在这里插一条:                  AND ECX, 0FF[/color]
004CE7BE    6BC9 24         IMUL ECX,ECX,24
004CE7C1    81C1 502C4B00   ADD ECX,Ekd5.004B2C50

这样就行了……

不过,能不能在技术上解释一下这里出问题的原因呢?谢谢。

2010-3-6 15:36 godtype
嗯,我开头也没有注意看。
因为 MOV DL,BYTE PTR DS:[ECX+1] 是单字节,而 MOV ECX,EDX 是四字节,所以要进行零扩展。
也可以改成以下几种方式:
1、在MOV DL,BYTE PTR DS:[ECX+1]的前面加一条XOR EDX,EDX
2、将MOV DL,BYTE PTR DS:[ECX+1]改成MOVZX EDX,BYTE PTR DS:[ECX+1]
以上两种都可以省去AND ECX,0FF
3、
MOV EDX,DWORD PTR SS:[EBP-4]
MOVZX ECX,BYTE PTR DS:[EDX+1]
这样还可以省多一条MOV ECX,EDX
4、将
AND ECX, 0FF
IMUL ECX,ECX,24
ADD ECX,Ekd5.004B2C50
写成一个自定义函数,直接CALL就是了,这样以后在其他地方修改也更方便一些。

页: [1]


Powered by Discuz! Archiver 5.0.0  © 2001-2006 Comsenz Inc.