I have a simple code:

void func()
{
    func2();
}

I omit the implementation of func2 and main since they are irrelevant. Then I used windbg to trace the assembly, following is the output of assembly code when executing "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)

We can see that before "push ebp" is executed, esp = 0012fe98, and ebp=0012ff68,but after executing "push ebp", esp=0012fdc8, ebp=0012fe94?, so I have two questions: 1. Presumably push code should only affect esp, why ebp is changed, too? 2. Presumably push ebp will push 4 bytes to stack, so the value of esp should decrease 4, but we see here that the value of esp descrease by 208 bytes? Why?

有帮助吗?

解决方案 2

As instructed by Steve Johnson, I uncheck "Source Mode" to trace the assembly, indeed after push ebp, there follows lots of (really lots of !) assembly code that were previous hidden when "Source Mode" was checked. So this case is solved, but I found other problems, first please see my more complete code:

void func();

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

void func()
{
    func2();
}

In func, I declare no local variables, following is the windbg output when I execute func() in main:

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

Indeed we see that after push ebp, it is mov ebp, esp, that actually changes ebp, but there is a code "sub esp,0C0h" following "mov ebp, esp", I know that "sub esp, num" is to allocate memory space for local variables on the stack frame, but I didn't declare local variables in func, so I have this questions: What does "sub esp, 0C0h" do here? Staring with function prolog, the uf output is:

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

其他提示

If you want to see what each individual instruction is doing, you need to disable source-level debugging. Open the debug menu and uncheck "Source Mode". When you step in source mode, all instructions mapped to the current source line are executed before the debugger breaks.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top