News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

push/pop ax

Started by Ryan, May 30, 2012, 02:11:56 PM

Previous topic - Next topic

Ryan

My development computer is running Windows 7 64-bit.  I'm in the process of writing a program to use for work.  It would need to be used on other computers, not just mine.  Some of them are XP.

I've got XP mode on my computer, so I decided to try my new program in it.  It wasn't working.  I just spent a few hours trying to track it down.  My program reads a file, but it has to seek to different points in the file.  I'm using CreateFile/ReadFile with SetFilePointer to move around.  I finally was able to fix it in XP mode by changing a push/pop to eax instead of ax.  I even tried pushing individual parameters instead of using invoke for SetFilePointer.  I was assigning each immediate value to edx before pushing it onto the stack.  I thought on the offhand chance it wasn't pushing a full 32-bit value, that would force it.

Does XP/XP mode not like pushing 16-bit values onto the stack?  I was testing the same executable in XP mode at the same time I was using it in Windows 7 with different results.

MichaelW

In 32-bit code pushing/popping 16-bit operands will disturb the required dword alignment of the stack pointer.


;==============================================================================
    include \masm32\include\masm32rt.inc
;==============================================================================

;----------------------------------------
; Returns the maximum alignment of _ptr.
;----------------------------------------

alignment MACRO _ptr
    push ecx
    xor eax, eax
    mov ecx, _ptr
    bsf ecx, ecx
    jz @F
    mov eax, 1
    shl eax, cl
  @@:
    pop ecx
    EXITM <eax>
ENDM

;==============================================================================
    .data
    .code
;==============================================================================
start:
;==============================================================================
    mov ebx, esp
    printf("%d\n",alignment(ebx))
    push ax                         ; misalign
    mov ebx, esp
    pop ax                          ; realign to avoid hang
    printf("%d\n",alignment(ebx))
    mov ebx, esp
    printf("%d\n",alignment(ebx))
    push eax
    pop ax                          ; misalign
    mov ebx, esp
    pop ax                          ; realign to avoid hang
    printf("%d\n",alignment(ebx))
    mov ebx, esp
    printf("%d\n\n",alignment(ebx))

    inkey "Press any key to exit..."
    exit
;==============================================================================
end start


For a demonstration of what happens when the stack pointer is not properly aligned, comment out one of the realign-to-avoid-hang instructions.

I can't think of any situation where this would be necessary, but if you must push/pop 16-bit operands you can maintain the alignment by pairing the operations, something like this:

    push ax                         ; misalign
    push dx                         ; realign
    . . .
    pop dx                          ; misalign
    pop ax                          ; realign


Also, pushing an immediate value is not generally a problem as the value will be extended to 32 bits, but in my test I could cause a misaligment with code like this (tested with ML 6.15 only):

push WORD PTR 1234
Well Microsoft, here's another nice mess you've gotten us into.

Ryan

Thank you Michael.  That makes sense.

jj2007

Classical example:

include \masm32\include\masm32rt.inc

.code
start: push ax
MsgBox 0, "Hello World", "Ouch", MB_OK
pop ax
exit

end start

xandaz

   althought it will work inside code that doesnt call any function between the align/misalign process.

dedndave

i have done something like this before
        push    dx
        push    ax

although - because of the size over-rides, you might be better off with...
        push    eax
        mov     [esp+2],dx

Ryan

Thank you all.

It's not that I needed to push a 16-bit value; it is just the amount of data I needed saved around API calls.  Pushing a 32-bit value will work just fine for my needs.

Antariy

#7
Quote from: jj2007 on May 30, 2012, 10:16:56 PM
Classical example:

:biggrin:

Quote from: xandaz on May 30, 2012, 11:14:02 PM
   althought it will work inside code that doesnt call any function between the align/misalign process.

Generally speaking - it will not work. If any exception in the code will occur - program will terminate silently without any error messages (SEH does check stack alignment).

http://www.movsd.com/board/index.php?topic=16285.msg134673#msg134673

With corrected link, picture from that post is:


Important note:
Images-as-zip posting method showed one drawback - images do not show when domain name changed.
So, it is better to use relative paths to archives as links to images.
Test: instead of http://masm32.com/board/index.php?action=dlattach;topic=114.0;attach=64 will try to use /board/index.php?action=dlattach;topic=114.0;attach=64



Result: it works, but forum engine seems to change relative path to full path anyway.

Admin' EDIT: The Above 'links' No longer Work