1

This is the code i copied from a Stackoverflow.com's Question:

global _main
    extern  _GetStdHandle@4
    extern  _WriteFile@20
    extern  _ExitProcess@4

    section .text
_main:
    ; DWORD  bytes;    
    mov     ebp, esp
    sub     esp, 4

    ; hStdOut = GetstdHandle( STD_OUTPUT_HANDLE)
    push    -11
    call    _GetStdHandle@4
    mov     ebx, eax    

    ; WriteFile( hstdOut, message, length(message), &bytes, 0);
    push    0
    lea     eax, [ebp-4]
    push    eax
    push    (message_end - message)
    push    message
    push    ebx
    call    _WriteFile@20

    ; ExitProcess(0)
    push    0
    call    _ExitProcess@4

    ; never here
    hlt
message:
    db      'Hello, World', 10
message_end:

This Code works correctly, No errors needs to be cleared, But there have some lines which im unable to understand what does they do, Scroll down:

MOV ebp, esp

Okay anyone can tell this copies the contents of esp to ebp register, But how can this be possible to copy a uninitialised register's value to a register? Will it load ebp with a 0 (Zero)?

SUB esp, 4

Here esp is being subtracted by 4, So 0-4= -4, Is'nt it?? But why this Two lines of code? instead if the result is to be the result which i given "-4" i would have Normaly do MOV esp, -4

MOV ebx, eax

And the eax, which i think must be filled by _GetstdHandle function?

and the last one, hlt?

Community
  • 1
  • 1
Rishabh
  • 35
  • 7
  • 1
    `esp` isn't uninitialized. When your application is started, a stack is created for its main thread, and `esp` will point to the top of that stack. – Michael Jan 20 '15 at 08:41

2 Answers2

2
  1. esp can never be "uninitialized". It always points to the top of the stack - where you push and pop things. For example, when you push a 32 bit register, esp is automatically decreased by four.

  2. The "sub esp, 4" allocates four bytes on the stack - for the "bytes" variable. Later you can see "lea ax, [ebp-4]", which corresponds to "&bytes" in the comment.

  3. Quite right, eax is returned from _GetStdHandle.

  4. "hlt" halts the processor - a bad thing. But as the comment says - is wll not be executed since _ExitProcess won't return. The idea might be that if _ExitProcess should return, it is better to halt than to start execute random code.

Dan Byström
  • 9,067
  • 5
  • 38
  • 68
  • The "hlt" instruction would not work in a Windows program at all. It would wait for the next interrupt if called from kernel context. Because it is a privileged instruction it would cause a fault when being called from a user-mode program! – Martin Rosenau Jan 20 '15 at 10:59
2

Summarized, this program creates a stack frame with one local variable, then calls Win32 API functions from kernel32.lib imported by the 'extern's above and exits with SUCCESS (0).

mov ebp, esp

sets the base pointer register with the current value of SS:ESP. This is done for accessing the local DWORD variable (4 bytes) reserved with

sub esp, 4

The stack grows downwards, for example: if ESP is 0FFFF0000h set by the OS on program start, EBP will be set to this value and the substraction will decrease it to 0FFFEFFFCh giving space for the local 4 byte var @ this address, which will be referenced later by

lea     eax, [ebp-4]      ; &bytes

The line

mov ebx, eax

saves the handle in EAX in EBX (which is not neccessary in this case), because

Registers EBP, EBX, ESI, and EDI are preserved during Win32 API calls.

The HLT at the end is unreachable code and therefore should never be executed. Anyway, it would stop the further execution, see here: http://www.felixcloutier.com/x86/HLT.html

zx485
  • 28,498
  • 28
  • 50
  • 59