News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

About structures in the stack

Started by felipe, July 20, 2017, 04:32:24 PM

Previous topic - Next topic

felipe

Why structures like wndclassex or msg are stored in stack (for example when you use the local directive, for these structures in the "winmain" typical procedure) with their elements stored backwards? I mean the first element in the wndclassex structure (sbsize) is in the lower addresses, but the last element of this structure (iconsm or something like that) is in the higher addresses of the stack, and so on.
Is this some convention of the assembler, windows, the linker or i'm just missing something important about the "processor rules"?

Btw. with lower and higher addresses in the stack i mean memory addresses and not to how the stack grows to lower addresses and decrease to higher ones.

Maybe it have to do with the little endian thing? Well i really want to know and i'm too tired to think now.  ;)

Thanks.  ;)

jj2007

Here is a little testbed showing 4 methods to create a RECT structure. Use it with Olly, and watch in particular the stack.

include \masm32\include\masm32rt.inc

.data
MyRect RECT <12h, 34h, 56h, 78h>

.code
MyTest proc uses edi
Local rc:RECT
  int 3  ; right-click on esp, "Follow in Dump"
  mov rc.left, 11111111h
  mov rc.top, 22222222h
  mov rc.right, 33333333h
  mov rc.bottom, 44444444h
  sub esp, RECT
  mov edi, esp
  rc2 equ [edi.RECT]
  mov rc2.left, 11111101h
  mov rc2.top, 22222202h
  mov rc2.right, 33333303h
  mov rc2.bottom, 44444404h
  print hex$(MyRect.right), 9, "global right", 13, 10
  print hex$(rc.right), 9, "local right", 13, 10
  print hex$(rc2.right), 9, "rc2/edi right", 13, 10
  push 44404444h
  push 33303333h
  push 22202222h
  push 11101111h
  mov edi, esp
  print hex$(rc2.right), 9, "manually pushed right", 13, 10
  add esp, 2*RECT
  ret
MyTest endp

start:
  mov eax, offset MyRect  ; right-click on eax, "Follow in Dump"
  int 3  ; for Olly
  call MyTest
  exit

end start


Output:00000056        global right
33333333        local right
33333303        rc2/edi right
33303333        manually pushed right

felipe

Quote from: felipe on July 20, 2017, 04:32:24 PM
Maybe it have to do with the little endian thing?
I must be very tired  :lol:.

Quote from: jj2007 on July 20, 2017, 04:57:32 PM


.code
MyTest proc uses edi
Local rc:RECT
  int 3     ; right-click on esp, "Follow in Dump"
  mov rc.left, 11111111h
  mov rc.top, 22222222h
  mov rc.right, 33333333h
  mov rc.bottom, 44444444h

Ok so until here we have that situation that i was talking about.


  sub esp, RECT
  mov edi, esp
  rc2 equ [edi.RECT]
  mov rc2.left, 11111101h
  mov rc2.top, 22222202h
  mov rc2.right, 33333303h
  mov rc2.bottom, 44444404h

But until here, i'm a little confussed, is this in the stack or not? I think is not, but why doing this if not?: sub esp, RECT


I will continue analyzing this tomorrow, now i have to sleep a little, thanks a lot jj!  :t

jj2007

  sub esp, RECT  ; create a RECT on the stack
  mov edi, esp  ; point to it with edi
  rc2 equ [edi.RECT]   ; define a RECT
  mov rc2.left, 11111101h  ; use it


You will understand it better when using the debugger.
Note that
  push eax
and
  sub esp, DWORD
  mov [esp], eax

have the same effect.

hutch--



    sub esp, 96                             ; create stack space for locals
  ; -----------------------------------
  ; manually coded WNDCLASSEX structure
  ; -----------------------------------
    mov DWORD PTR [ebp-96], 48
    mov DWORD PTR [ebp-92], CS_VREDRAW or CS_HREDRAW
    mov DWORD PTR [ebp-88], OFFSET MyWndProc
    mov DWORD PTR [ebp-84], edi
    mov DWORD PTR [ebp-80], edi
    mov DWORD PTR [ebp-76], esi
    mov DWORD PTR [ebp-72], edi
    mov DWORD PTR [ebp-68], eax
    mov DWORD PTR [ebp-64], COLOR_BTNFACE+1
    mov DWORD PTR [ebp-60], edi
    mov DWORD PTR [ebp-56], ebx
    mov DWORD PTR [ebp-52], edi

    lea eax, [ebp-96]
    push eax
    call RegisterClassEx                    ; register the window class

aw27

not a "little endian thing" but a "bottom up thing"  :icon_cool:

felipe

Quote from: jj2007 on July 20, 2017, 05:59:51 PM
  sub esp, RECT  ; create a RECT on the stack
  mov edi, esp  ; point to it with edi
  rc2 equ [edi.RECT]   ; define a RECT
  mov rc2.left, 11111101h  ; use it


You will understand it better when using the debugger.
Note that
  push eax
and
  sub esp, DWORD
  mov [esp], eax

have the same effect.

I guess i was confused about if this were in the stack because olly showed me code like this:
mov ds:[edi],11111101
mov ds:[edi],etc

felipe

Quote from: aw27 on July 20, 2017, 10:02:09 PM
not a "little endian thing" but a "bottom up thing"  :icon_cool:

Yeah, later in the night i thought that is logical that the first elements of the structures were in the lower addresses.  :P

felipe

Quote from: hutch-- on July 20, 2017, 09:11:07 PM


    sub esp, 96                             ; create stack space for locals
  ; -----------------------------------
  ; manually coded WNDCLASSEX structure
  ; -----------------------------------
    mov DWORD PTR [ebp-96], 48
    mov DWORD PTR [ebp-92], CS_VREDRAW or CS_HREDRAW
    mov DWORD PTR [ebp-88], OFFSET MyWndProc
    mov DWORD PTR [ebp-84], edi
    mov DWORD PTR [ebp-80], edi
    mov DWORD PTR [ebp-76], esi
    mov DWORD PTR [ebp-72], edi
    mov DWORD PTR [ebp-68], eax
    mov DWORD PTR [ebp-64], COLOR_BTNFACE+1
    mov DWORD PTR [ebp-60], edi
    mov DWORD PTR [ebp-56], ebx
    mov DWORD PTR [ebp-52], edi

    lea eax, [ebp-96]
    push eax
    call RegisterClassEx                    ; register the window class



sub         esp,76                                                      ; 48 bytes for wc + 28 bytes for msg.

strucclass:
            mov         dword ptr[ebp-48],48                                        ; Size of wc.
            mov         dword ptr[ebp-44],CS_HREDRAW or CS_VREDRAW
            mov         dword ptr[ebp-40],wndproc
            mov         dword ptr[ebp-36],NULL
            mov         dword ptr[ebp-32],NULL
            mov         eax,[ebp+8]                                                 ; hmodule.
            mov         [ebp-28],eax
            push        IDI_APPLICATION
            push        NULL
            call        LoadIcon
            mov         [ebp-24],eax
            ;mov         [ebp-4],eax
            push        IDC_ARROW
            push        NULL
            call        LoadCursor
            mov         [ebp-20],eax
            mov         dword ptr[ebp-16],COLOR_WINDOW+1
            mov         dword ptr[ebp-12],NULL
            lea         eax,classname
            mov         [ebp-8],eax
            mov         dword ptr[ebp-4],NULL
            lea         eax,[ebp-48]
            push        eax
            call        RegisterClassEx


:greensml:

felipe

jj i will continue with your code in a moment  :bgrin:
Btw, which is the current version downloadable of olly?
I got version 1.x  :redface:
I can follow esp in the dump but i can't do the same for eax.

felipe

Quote from: jj2007 on July 20, 2017, 04:57:32 PM
Here is a little testbed showing 4 methods to create a RECT structure. Use it with Olly, and watch in particular the stack.

include \masm32\include\masm32rt.inc

.data
MyRect RECT <12h, 34h, 56h, 78h>

.code
MyTest proc uses edi
Local rc:RECT
  int 3  ; right-click on esp, "Follow in Dump"
  mov rc.left, 11111111h
  mov rc.top, 22222222h
  mov rc.right, 33333333h
  mov rc.bottom, 44444444h
  sub esp, RECT
  mov edi, esp
  rc2 equ [edi.RECT]
  mov rc2.left, 11111101h
  mov rc2.top, 22222202h
  mov rc2.right, 33333303h
  mov rc2.bottom, 44444404h
  print hex$(MyRect.right), 9, "global right", 13, 10
  print hex$(rc.right), 9, "local right", 13, 10
  print hex$(rc2.right), 9, "rc2/edi right", 13, 10
  push 44404444h
  push 33303333h
  push 22202222h
  push 11101111h
  mov edi, esp
  print hex$(rc2.right), 9, "manually pushed right", 13, 10
  add esp, 2*RECT
  ret
MyTest endp

start:
  mov eax, offset MyRect  ; right-click on eax, "Follow in Dump"
  int 3  ; for Olly
  call MyTest
  exit

end start


Output:00000056        global right
33333333        local right
33333303        rc2/edi right
33303333        manually pushed right


Ok, i think i now understand your code:
1) The four ways are those in the .code section and the one in the .data section, right?  ;)
2) Seems like the answer of my first question is simply that the first elements of the structure should be stored in the lower addresses.
3) Esp can't be used as an index, so edi will do this job (for the third way).
4) So finally, all this ways store the structure elementes in the same order in memory: First elements in lower addresses.

Ok, i think i get it, but i have one doubt:
The reason for this:
mov ds:[edi],1111etc
Is because ds is pointing to the same place of ss? Because of the flat memory model?

Thanks alot to all like always!  :t

aw27

Quote from: felipe on July 21, 2017, 03:25:34 AM
Ok, i think i get it, but i have one doubt:
The reason for this:
mov ds:[edi],1111etc
Is because ds is pointing to the same place of ss? Because of the flat memory model?

Oly has in their roadmap to change that to mov edi, 1111
May take another 13 years though.   :biggrin:

jj2007

Quote from: felipe on July 21, 2017, 03:25:34 AM
1) The four ways are those in the .code section and the one in the .data section, right?  ;)

Right.

Quote2) Seems like the answer of my first question is simply that the first elements of the structure should be stored in the lower addresses.

Exactly: Little Endian.

Quote3) Esp can't be used as an index, so edi will do this job (for the third way).

mov [esp.RECT.left], 123 works, too. I used edi as a habit because often esp gets changed by a simple push or pop, so having a "stable reference" is often a good idea. But in this specific case you can just use esp instead of edi.

QuoteThe reason for this:
mov ds:[edi],1111etc
Is because ds is pointing to the same place of ss? Because of the flat memory model?

No, it's simply because Options/Code/Show default segments is enabled. Untick the box.
Note this is Olly 2, in version it's under Options/Debugging options/Disasm.

felipe