首页
社区
课程
招聘
[win32汇编] lea指令为什么不能用addr 代替呢?
发表于: 2015-1-26 20:24 4475

[win32汇编] lea指令为什么不能用addr 代替呢?

2015-1-26 20:24
4475
新人第一求问贴 在线等
_ProcDlgMain        proc        uses ebx edi esi hWnd,wMsg,wParam,lParam
                local        @szBuffer[128]:byte
                mov        eax,wParam
                if    ax ==        IDC_LISTBOX1
                      shr        eax,16

                       if    ax ==        LBN_DBLCLK

                            invoke        SendMessage,lParam,LB_GETCURSEL,0,0
                            lea        ecx,@szBuffer
                            invoke        SendMessage,lParam,LB_GETTEXT,eax,ecx
                       .endif                .
               .endif
                mov        eax,TRUE
                ret

_ProcDlgMain        endp

上面子程序里面的这两句代码为什么不能
                            lea        ecx,@szBuffer
                            invoke        SendMessage,lParam,LB_GETTEXT,eax,ecx
改成
                            invoke        SendMessage,lParam,LB_GETTEXT,eax,addr @szBuffer
我是菜鸟 自认为 lea指令就是拿局部变量 @szBuffer的偏移地址 其实 addr @szBuffer 也就是传的是偏移地址嘛 为什么编译器报下面的错
——————————————————————————

Assembling: Listbox.asm
Listbox.asm(118) : error A2133: register value overwritten by INVOKE
NMAKE : fatal error U1077: 'ml' : return code '0x1'
Stop.
——————————————————————————
希望大家不吝赐教

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 276
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
已经知道答案了 结贴
因为且 addr 的对象是个局部变量 的话 编译器会使用寄存器eax。
此时 eax 的值已被更改 你不能再用它作为此函数的 参数了
2015-1-26 20:48
0
雪    币: 39
活跃值: (2931)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
自以为是了吧。
局部变量是用[ebp-n]这种形式构造的,
跟EAX没有任何关系。
而[ebp-n]是不可以用addr或offset取其偏移地址的,只能用lea。
2015-1-26 22:01
0
雪    币: 276
活跃值: (10)
能力值: ( 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

这又作何解释呢?
2015-2-1 18:03
0
雪    币: 39
活跃值: (2931)
能力值: ( 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]
这种全部自己来。
2015-2-6 11:25
0
雪    币: 276
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
谢谢了受教了,目前我发觉自己的最大问题是
对内存的分布不熟悉,局部变量啊 全局变量啊 等等的实现机制看来得好好看看编译后的代码
2015-2-7 09:57
0
游客
登录 | 注册 方可回帖
返回
//