我是一名新学员,我不会用英语写作。我从许多来源读到,要在过程中访问局部变量,首先使用[ebp-4]
访问本地。我让这个程序显示EAX
,并且只显示一个本地数据(string
)。发生了什么[ebp-4]
没有用。我改为[ebp-8]并且它有效。为什么这样?
mov eax,0x0ffffc345
push eax
call Disp_EAX
call exit
Disp_EAX:
push ebp
mov ebp,esp
sub esp,12 ;for string to display EAX
cld
lea edi,[ebp-8] ;why can't [ebp-4]?
mov esi,8
mov edx,[ebp+8]
mov eax,0
extract:
shld eax,edx,4
add al,0x30
cmp al,0x39
jle continue
add eax,7
continue:
stosb
dec esi
cmp esi,0
je done
rol edx,4
xor al,al
jmp extract
done:
mov eax,0
stosb
lea esi,[ebp-8]
cinvoke printf,esi
add esp,12
mov esp,ebp
pop ebp
ret
希望你能帮助我理解。
添加:如果我使用[ebp-4]
,我的程序会连续循环,但显示正确。我真的很困惑。
答案 0 :(得分:0)
堆栈在x86上向下增长。如果设置标准堆栈帧,ebp
指向局部变量末尾的一个,从当前值esp
开始。因此,您有ebp
- esp
字节的本地人。
您使用sub esp, 12
分配12个字节,因此该块的地址为ebp-12
。在循环中,您使用该块的8个字节。如果您从ebp-8
开始,那么您正在通过ebp-8
撰写ebp-1
并且一切正常,那就在您的本地区域内。如果您使用ebp-4
,则从ebp-4
写入ebp+3
这是不好的,因为最后4个字节不在为本地变量分配的块中。您将覆盖ebp
放置在堆栈上的已保存push ebp
,这将导致无法预料的问题。