Author Topic: push/pop ax  (Read 8085 times)

Ryan

  • Guest
push/pop ax
« on: May 30, 2012, 02:11:56 PM »
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

  • Global Moderator
  • Member
  • *****
  • Posts: 1209
Re: push/pop ax
« Reply #1 on: May 30, 2012, 03:10:04 PM »
In 32-bit code pushing/popping 16-bit operands will disturb the required dword alignment of the stack pointer.

Code: [Select]
;==============================================================================
    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:
Code: [Select]
    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):
Code: [Select]
push WORD PTR 1234
Well Microsoft, here’s another nice mess you’ve gotten us into.

Ryan

  • Guest
Re: push/pop ax
« Reply #2 on: May 30, 2012, 09:19:36 PM »
Thank you Michael.  That makes sense.

jj2007

  • Member
  • *****
  • Posts: 7546
  • Assembler is fun ;-)
    • MasmBasic
Re: push/pop ax
« Reply #3 on: May 30, 2012, 10:16:56 PM »
Classical example:

Code: [Select]
include \masm32\include\masm32rt.inc

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

end start

xandaz

  • Member
  • **
  • Posts: 91
  • I luv you babe
Re: push/pop ax
« Reply #4 on: May 30, 2012, 11:14:02 PM »
   althought it will work inside code that doesnt call any function between the align/misalign process.

dedndave

  • Member
  • *****
  • Posts: 8734
  • Still using Abacus 2.0
    • DednDave
Re: push/pop ax
« Reply #5 on: May 31, 2012, 12:07:08 AM »
i have done something like this before
Code: [Select]
        push    dx
        push    ax
although - because of the size over-rides, you might be better off with...
Code: [Select]
        push    eax
        mov     [esp+2],dx

Ryan

  • Guest
Re: push/pop ax
« Reply #6 on: May 31, 2012, 02:48:11 AM »
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

  • Member
  • ****
  • Posts: 541
Re: push/pop ax
« Reply #7 on: May 31, 2012, 11:40:24 AM »
Classical example:

:biggrin:

   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.