Can anyone help me interpret this simple disassembly from WinDbg?

前端 未结 5 1125
野性不改
野性不改 2020-12-23 08:34

I got the following simple C++ code:

#include 
int main(void)
{
    ::printf(\"\\nHello,debugger!\\n\");
}

And from WinDbg,

5条回答
  •  无人及你
    2020-12-23 09:15

    I've annotated the assembler, hopefully that will help you a bit. Lines starting 'd' are debug code lines, lines starting 'r' are run time check code lines. I've also put in what I think a debug with no runtime checks version and release version would look like.

      ; The ebp register is used to access local variables that are stored on the stack, 
      ; this is known as a stack frame. Before we start doing anything, we need to save 
      ; the stack frame of the calling function so it can be restored when we finish.
      push    ebp                   
      ; These two instructions create our stack frame, in this case, 192 bytes
      ; This space, although not used in this case, is useful for edit-and-continue. If you
      ; break the program and add code which requires a local variable, the space is 
      ; available for it. This is much simpler than trying to relocate stack variables, 
      ; especially if you have pointers to stack variables.
      mov     ebp,esp             
    d sub     esp,0C0h              
      ; C/C++ functions shouldn't alter these three registers in this build configuration,
      ; so save them. These are stored below our stack frame (the stack moves down in memory)
    r push    ebx
    r push    esi
    r push    edi                   
      ; This puts the address of the stack frame bottom (lowest address) into edi...
    d lea     edi,[ebp-0C0h]        
      ; ...and then fill the stack frame with the uninitialised data value (ecx = number of
      ; dwords, eax = value to store)
    d mov     ecx,30h
    d mov     eax,0CCCCCCCCh     
    d rep stos dword ptr es:[edi]   
      ; Stack checking code: the stack pointer is stored in esi
    r mov     esi,esp               
      ; This is the first parameter to printf. Parameters are pushed onto the stack 
      ; in reverse order (i.e. last parameter pushed first) before calling the function.
      push    offset SimpleDemo!`string' 
      ; This is the call to printf. Note the call is indirect, the target address is
      ; specified in the memory address SimpleDemo!_imp__printf, which is filled in when
      ; the executable is loaded into RAM.
      call    dword ptr [SimpleDemo!_imp__printf] 
      ; In C/C++, the caller is responsible for removing the parameters. This is because
      ; the caller is the only code that knows how many parameters were put on the stack
      ; (thanks to the '...' parameter type)
      add     esp,4                 
      ; More stack checking code - this sets the zero flag if the stack pointer is pointing
      ; where we expect it to be pointing. 
    r cmp     esi,esp               
      ; ILT - Import Lookup Table? This is a statically linked function which throws an
      ; exception/error if the zero flag is cleared (i.e. the stack pointer is pointing
      ; somewhere unexpected)
    r call    SimpleDemo!ILT+295(__RTC_CheckEsp)) 
      ; The return value is stored in eax by convention
      xor     eax,eax               
      ; Restore the values we shouldn't have altered
    r pop     edi
    r pop     esi
    r pop     ebx                   
      ; Destroy the stack frame
    r add     esp,0C0h              
      ; More stack checking code - this sets the zero flag if the stack pointer is pointing
      ; where we expect it to be pointing. 
    r cmp     ebp,esp               
      ; see above
    r call    SimpleDemo!ILT+295(__RTC_CheckEsp) 
      ; This is the usual way to destroy the stack frame, but here it's not really necessary
      ; since ebp==esp
      mov     esp,ebp               
      ; Restore the caller's stack frame
      pop     ebp                   
      ; And exit
      ret                           
    
    
      ; Debug only, no runtime checks  
      push    ebp                   
      mov     ebp,esp             
    d sub     esp,0C0h              
    d lea     edi,[ebp-0C0h]        
    d mov     ecx,30h
    d mov     eax,0CCCCCCCCh     
    d rep stos dword ptr es:[edi]   
      push    offset SimpleDemo!`string' 
      call    dword ptr [SimpleDemo!_imp__printf] 
      add     esp,4                 
      xor     eax,eax               
      mov     esp,ebp               
      pop     ebp                   
      ret                             
    
    
      ; Release mode (I'm assuming the optimiser is clever enough to drop the stack frame when there's no local variables)
      push    offset SimpleDemo!`string' 
      call    dword ptr [SimpleDemo!_imp__printf] 
      add     esp,4                 
      xor     eax,eax               
      ret                               
    

提交回复
热议问题