簡體   English   中英

為什么“ push ebp”會改變ebp的值?

[英]Why does “push ebp” change the value of ebp?

我有一個簡單的代碼:

void func()
{
    func2();
}

由於它們無關緊要,因此我省略了func2和main的實現。 然后,我使用windbg來跟蹤程序集,以下是執行“ func2()”時程序集代碼的輸出:

eax=cccccccc ebx=7ffd6000 ecx=00000000 edx=00000001 esi=01faf760 edi=0012ff68
eip=004113f0 esp=0012fe98 ebp=0012ff68 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
SimpleStack!func:
004113f0 55              push    ebp
0:000> t
eax=cccccccc ebx=7ffd6000 ecx=00000000 edx=00000001 esi=01faf760 edi=0012fe94
eip=0041140e esp=0012fdc8 ebp=0012fe94 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
SimpleStack!func+0x1e:
0041140e e83dfcffff      call    SimpleStack!ILT+75(_func2) (00411050)

我們可以看到,在執行“ push ebp”之前,esp = 0012fe98,並且ebp = 0012ff68,但是在執行“ push ebp”之后,esp = 0012fdc8,ebp = 0012fe94 ?,所以我有兩個問題:1.推入代碼應該僅影響esp,為什么ebp也被更改? 2.推入ebp可能會將4個字節壓入堆棧,因此esp的值應減少4,但是我們在這里看到esp的值減少了208個字節嗎? 為什么?

如果要查看每個單獨的指令在做什么,則需要禁用源代碼級調試。 打開調試菜單,然后取消選中“源模式”。 當您進入源代碼模式時,映射到當前源代碼行的所有指令都將在調試器中斷之前執行。

按照史蒂夫·約翰遜(Steve Johnson)的指示,我取消選中“源代碼模式”以跟蹤程序集,實際上在推入ebp之后,會出現很多(確實很多!)匯編代碼,這些代碼先前在檢查“源代碼模式”時被隱藏。 因此,這種情況已解決,但我發現了其他問題,請首先查看我更完整的代碼:

void func();

int main(int argc, char* argv[])
{
    func();
    return 0;
}
void func2();

void func()
{
    func2();
}

在func中,我沒有聲明任何局部變量,以下是在main中執行func()時的windbg輸出:

004113c3 50              push    eax
0:000> 
eax=0000000a ebx=7ffda000 ecx=00000000 edx=00000001 esi=01f1f760 edi=0012ff68
eip=004113c4 esp=0012fe98 ebp=0012ff68 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
SimpleStack!main+0x24:
004113c4 e8e0fdffff      call    SimpleStack!ILT+420(_func) (004111a9)
0:000> t
eax=0000000a ebx=7ffda000 ecx=00000000 edx=00000001 esi=01f1f760 edi=0012ff68
eip=004111a9 esp=0012fe94 ebp=0012ff68 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
SimpleStack!ILT+420(_func):
004111a9 e942020000      jmp     SimpleStack!func (004113f0)
0:000> t
eax=0000000a ebx=7ffda000 ecx=00000000 edx=00000001 esi=01f1f760 edi=0012ff68
eip=004113f0 esp=0012fe94 ebp=0012ff68 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
SimpleStack!func:
004113f0 55              push    ebp
0:000> t
eax=0000000a ebx=7ffda000 ecx=00000000 edx=00000001 esi=01f1f760 edi=0012ff68
eip=004113f1 esp=0012fe90 ebp=0012ff68 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
SimpleStack!func+0x1:
004113f1 8bec            mov     ebp,esp
0:000> t
eax=0000000a ebx=7ffda000 ecx=00000000 edx=00000001 esi=01f1f760 edi=0012ff68
eip=004113f3 esp=0012fe90 ebp=0012fe90 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
SimpleStack!func+0x3:
004113f3 81ecc0000000    sub     esp,0C0h
0:000> t
eax=0000000a ebx=7ffda000 ecx=00000000 edx=00000001 esi=01f1f760 edi=0012ff68
eip=004113f9 esp=0012fdd0 ebp=0012fe90 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
SimpleStack!func+0x9:
004113f9 53              push    ebx
0:000> t
eax=0000000a ebx=7ffda000 ecx=00000000 edx=00000001 esi=01f1f760 edi=0012ff68
eip=004113fa esp=0012fdcc ebp=0012fe90 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
SimpleStack!func+0xa:
004113fa 56              push    esi

的確,我們看到在push ebp之后,實際上是mov ebp,esp更改了ebp,但是在“ mov ebp,esp”之后有一個代碼“ sub esp,0C0h”,我知道“ sub esp,num”是在堆棧框架上為局部變量分配內存空間,但是我沒有在func中聲明局部變量,所以我有以下問題:“ sub esp,0C0h”在這里做什么? 從函數序言開始,uf輸出為:

0:000> uf func
SimpleStack!func [d:\code\simplestack\func.c @ 4]:
    4 004113f0 55              push    ebp
    4 004113f1 8bec            mov     ebp,esp
    4 004113f3 81ecc0000000    sub     esp,0C0h
    4 004113f9 53              push    ebx
    4 004113fa 56              push    esi
    4 004113fb 57              push    edi
    4 004113fc 8dbd40ffffff    lea     edi,[ebp-0C0h]
    4 00411402 b930000000      mov     ecx,30h
    4 00411407 b8cccccccc      mov     eax,0CCCCCCCCh
    4 0041140c f3ab            rep stos dword ptr es:[edi]
    5 0041140e e83dfcffff      call    SimpleStack!ILT+75(_func2) (00411050)
    6 00411413 5f              pop     edi
    6 00411414 5e              pop     esi
    6 00411415 5b              pop     ebx
    6 00411416 81c4c0000000    add     esp,0C0h
    6 0041141c 3bec            cmp     ebp,esp
    6 0041141e e818fdffff      call    SimpleStack!ILT+310(__RTC_CheckEsp) (0041113b)
    6 00411423 8be5            mov     esp,ebp
    6 00411425 5d              pop     ebp
    6 00411426 c3

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM