News:

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

Main Menu

Aligning stack parameters

Started by masterori, February 15, 2016, 09:50:51 AM

Previous topic - Next topic

masterori

So since the stack frame is based on a dword boundary, should I make all stack parameters dword? Or can I do something like:

    welcome_text  byte  "something goes here",0
    ...
    push  dword ptr offset welcome_text

jj2007

No problem: You are pushing an offset, which is a DWORD, like any other address in Win32.

masterori

In terms of pushing a non offset/dword variable onto the stack. How do I go about making sure that it aligns? Would it be with the ptr?

jj2007

You cannot push a byte (there is no instruction for it).
You can indeed push a word with pushw:

include \masm32\MasmBasic\MasmBasic.inc      ; download
  Init
  pushw 0
  MsgBox 0, "Hello", "Hi", MB_OK
  pop ax
print "it's OK"
EndOfCode


On Win7-64, the MessageBox works fine, on Windows XP I've seen very odd behaviour.

The cpu itself has no problems with a word-aligned stack, but some Windows API functions may behave in an unpredictable way. In any case, there is no need to word-align the stack. Never.

Note that although there is no pushb, you can simulate it:

include \masm32\MasmBasic\MasmBasic.inc      ; download
  Init
  pushw 0d0ah
  inc esp
  MsgBox 0, "Hello", "Hi", MB_OK
  dec esp
  pop ax
print "it's OK"
EndOfCode


And that MsgBox definitely looks odd :P

hutch--

I am much of the view that you maintain the DWORD alignment on the stack. If you need to pass either BYTE or WORD data, write it to either the low byte or low word of a DWORD and pass it on the stack like normal.

dedndave

it's safe to assume that the stack is previously aligned (ESP initially holds an address that is divisable by 4)
so, as long as you push only dwords, and add to or subtract from ESP only values divisable by 4, the stack will remain aligned

masterori

Quote from: hutch-- on February 15, 2016, 11:33:44 AM
If you need to pass either BYTE or WORD data, write it to either the low byte or low word of a DWORD and pass it on the stack like normal.
What do you mean write to the low byte/word of a dword?

Here's an example from a quiz problem that I got wrong:

.data
x   DWORD  153461
y   WORD   37
z   WORD   90


.code
main PROC
   push  x
   push  y
   push  z
   call  someProcedure
   ...
   exit
main ENDP

someProcedure PROC
   push ebp
   mov ebp, esp
   ...

   pop ebp
   ret 8
someProcedure ENDP
END MAIN


According to the answers:

[ebp + 8]           ; holds 90
[ebp + 10]         ; holds 37
[ebp + 12]         ; holds 153461


Assuming [ebp + 4] holds the address of someProcedure, if the stack frame is dword aligned, then [ebp + 8] holds z (or 90). But why did x and y only increment by twos?

hutch--

Well, the low byte of the EAX register is AL, the low WORD is AX.


xor eax, eax    ; set the reg to ZERO
mov al, bytevalue

xor eax, eax
mov ax, wordvalue

FORTRANS

Hi,

Quote from: masterori on February 18, 2016, 03:38:44 PM
But why did x and y only increment by twos?

   Because x and y were declared to be WORDs, they are only two
bytes long.  A 32-bit X86 processor can PUSH either a word value
or a double word value.  What the posts above are saying is, in a
Windows program you should avoid pushing word values to keep
the stack aligned on a four byte value.

HTH,

Steve N.