能力值:
( LV2,RANK:10 )
2 楼
已经知道答案了 结贴
因为且 addr 的对象是个局部变量 的话 编译器会使用寄存器eax。
此时 eax 的值已被更改 你不能再用它作为此函数的 参数了
能力值:
( LV2,RANK:10 )
3 楼
自以为是了吧。
局部变量是用[ebp-n]这种形式构造的,
跟EAX没有任何关系。
而[ebp-n]是不可以用addr或offset取其偏移地址的,只能用lea。
能力值:
( LV2,RANK:10 )
4 楼
[QUOTE=NutCracker;1349641]自以为是了吧。
局部变量是用[ebp-n]这种形式构造的,
跟EAX没有任何关系。
而[ebp-n]是不可以用addr或offset取其偏移地址的,只能用lea。[/QUOTE]
谢谢大哥回复,听你的意思
在我的这个例子里面是局部变量所以只能用lea。
但是在我经常看见在子程序里面局部变量用 addr
例如
local @szBuffer[128]:byte
invoke wsprintf,addr @szBuffer,addr szFormat,wParam
invoke MessageBox,hWnd,addr @szBuffer,addr szCaption,MB_OK or MB_ICONINFORMATION
这又作何解释呢?
能力值:
( LV2,RANK:10 )
5 楼
[QUOTE=ifbeyu;1350928]谢谢大哥回复,听你的意思
在我的这个例子里面是局部变量所以只能用lea。
但是在我经常看见在子程序里面局部变量用 addr
例如
local @szBuffer[128]:byte
invoke wsprintf,addr @szBuffer,addr szFormat,wParam
i...[/QUOTE]
你跟踪一下编译出来的EXE文件,看一下@szBuffer这个数组到底是
静态的还是动态的。如果是静态的话,是可以用addr @szBuffer这种
形式的,反之肯定不行。
给你看个例子:
函数f()的源代码:
f proc uses ebx esi edi x, y
local @buf[100h]:byte
mov eax, x
add eax, y
lea ebx, @buf
mov [ebx], eax
ret
f endp
编译出来变成:
00401000 /$ 55 push ebp
00401001 |. 8BEC mov ebp, esp
00401003 |. 81C4 00FFFFFF add esp, -0x100
00401009 |. 53 push ebx
0040100A |. 56 push esi
0040100B |. 57 push edi
0040100C |. 8B45 08 mov eax, [ebp+0x8]
0040100F |. 0345 0C add eax, [ebp+0xC]
00401012 |. 8D9D 00FFFFFF lea ebx, [ebp-0x100]
00401018 |. 8903 mov [ebx], eax
0040101A |. 5F pop edi
0040101B |. 5E pop esi
0040101C |. 5B pop ebx
0040101D |. C9 leave
0040101E \. C2 0800 retn 0x8
显然,数组@buf是动态的,它的首地址为ebp-100h。
你要是想取它的地址必须用lea ebx, @buf,改成mov ebx, addr @buf或者mov ebx, offset @buf肯定错。
建议你在学习“高级”用法前,先掌握“低级”的用法,就是老老实实用call,而不用invoke,
函数定义不用xxx proc uses ...这种形式,而用xxx:代替,里面的参数处理像[ebp+8]这种及动态变量[ebp-100h]
这种全部自己来。
能力值:
( LV2,RANK:10 )
6 楼
谢谢了受教了,目前我发觉自己的最大问题是
对内存的分布不熟悉,局部变量啊 全局变量啊 等等的实现机制看来得好好看看编译后的代码