The MASM Forum

General => The Campus => Topic started by: gelatine1 on June 20, 2014, 05:21:26 AM

Title: push 0 appearing in between a function call ?
Post by: gelatine1 on June 20, 2014, 05:21:26 AM
Hello, another question once again... (I hope I'm not bothering too much)


invoke WriteFile, fhandle, [pmem], [bytesToWrite], edx, ecx


my code crashed, okay, I checked the debugger but I saw something very weird. The function above got assembled like this:
(http://s7.postimg.org/mmtl8m3yj/weirdpush.png)

I have no clue where this 0 comes from and I think it's not really normal. I believe it may be the cause of the crash (not sure though) but I have no clue what caused it or how to solve it.

Anyone knows what's going on ?

Thanks in advance,
Jannes
Title: Re: push 0 appearing in between a function call ?
Post by: dedndave on June 20, 2014, 06:02:30 AM
the problem is....
bytesToWrite is defined as a WORD and should be defined as a DWORD

it would appear that the assembler is trying to maintain stack alignment
Title: Re: push 0 appearing in between a function call ?
Post by: jj2007 on June 20, 2014, 06:23:22 AM
Quote from: dedndave on June 20, 2014, 06:02:30 AM
it would appear that the assembler is trying to maintain stack alignment

it would appear that the assembler (ML 6.14 or 6.15) is doing a lousy job: the push 0 is a dword :(

BTW, JWasm and ML 10 do it correctly via movzx eax:

push ecx                                    ; pOverlapped
push edx                                    ; pBytesWritten
movzx eax, word ptr [bytesToWrite]
push eax                                    ; Size
push dword ptr [pmem]                       ; Buffer = 123456
push dword ptr [fhandle]                    ; hFile = 11111111
call WriteFile                              ; KERNEL32.WriteFile


Which does not mean that anybody here or at MSDN endorses using a WORD for bytesToWrite, Jannes :eusa_naughty:
Title: Re: push 0 appearing in between a function call ?
Post by: dedndave on June 20, 2014, 06:36:01 AM
that's an official bug, then

it should burp, "Invalid argument size", or something of that nature
Title: Re: push 0 appearing in between a function call ?
Post by: dedndave on June 20, 2014, 06:48:21 AM
it's already on the list of known masm bugs - same for BYTE argument, as well
Title: Re: push 0 appearing in between a function call ?
Post by: KeepingRealBusy on June 20, 2014, 12:13:37 PM
Dave,

Which version of MASM?

Dave.
Title: Re: push 0 appearing in between a function call ?
Post by: dedndave on June 20, 2014, 12:22:56 PM
it seems to be 6.14 and 6.15, at least

Andreas (Japheth) keeps a list, i guess
Title: Re: push 0 appearing in between a function call ?
Post by: hutch-- on June 20, 2014, 12:36:19 PM
MASM bug = MASM feature you have not adapted to.  :biggrin:
Title: Re: push 0 appearing in between a function call ?
Post by: ragdog on June 20, 2014, 03:35:00 PM
Hi

A bug in Masm?!?

i have test it withhout push 0 and word ptr
I use masm32v10


.data
fhandle dd ?
pmem dd ?
nsize dd ?

invoke WriteFile, fhandle, [pmem], [nsize], edx, ecx



00401000 >/$  51            PUSH ECX                                 ; /pOverlapped = NULL
00401001  |.  52            PUSH EDX                                 ; |pBytesWritten = Console.<ModuleEntryPoint>
00401002  |.  FF35 08304000 PUSH DWORD PTR DS:[403008]               ; |nBytesToWrite = 0
00401008  |.  FF35 04304000 PUSH DWORD PTR DS:[403004]               ; |Buffer = NULL
0040100E  |.  FF35 00304000 PUSH DWORD PTR DS:[403000]               ; |hFile = NULL
00401014  |.  E8 43000000   CALL <JMP.&kernel32.WriteFile>           ; \WriteFile


Title: Re: push 0 appearing in between a function call ?
Post by: jj2007 on June 20, 2014, 04:24:30 PM
Quote from: dedndave on June 20, 2014, 12:22:56 PM
it seems to be 6.14 and 6.15, at least

Andreas (Japheth) keeps a list, i guess

Indeed, and it's bug #1 (http://www.japheth.de/JWasm/Manual.html#CHAPMASMBUGS) :P
Title: Re: push 0 appearing in between a function call ?
Post by: gelatine1 on June 20, 2014, 07:13:28 PM
Thanks for the help guys!
Indeed when I changed bytesToWrite to a dword everything worked well :)

Quote
   Which does not mean that anybody here or at MSDN endorses using a WORD for bytesToWrite, Jannes  :eusa_naughty:

Well I thought, bytesToWrite is small anyway so why not use a word (and save some very precious ram memory.. :p ) but I guess that was just a stupid idea :D
Title: Re: push 0 appearing in between a function call ?
Post by: dedndave on June 20, 2014, 07:55:43 PM
ragdog....
try defining one of those as a WORD
.data
fhandle dd ?
pmem dw ?
nsize dd ?
Title: Re: push 0 appearing in between a function call ?
Post by: jj2007 on June 20, 2014, 10:58:37 PM
Quote from: gelatine1 on June 20, 2014, 07:13:28 PM...so why not use a word (and save some very precious ram memory.. :p ) but I guess that was just a stupid idea :D

The idea as such is a good one, but Windows tends to be very strict regarding the parameters passed 8)
Go here and follow step 7 (http://www.webalice.it/jj2006/Masm32_Tips_Tricks_and_Traps.htm) to get an old but incredibly useful *.hlp file that will show you which parameters to pass.
Title: Re: push 0 appearing in between a function call ?
Post by: ragdog on June 21, 2014, 02:38:06 AM
Thanks Dave

But i think is not really a bug by Masm only by the user
Title: Re: push 0 appearing in between a function call ?
Post by: dedndave on June 21, 2014, 04:01:45 AM
well - the bug is: masm should report an error in argument size
or maintain stack alignment, somehow
Title: Re: push 0 appearing in between a function call ?
Post by: MichaelW on June 21, 2014, 04:52:49 AM
MASM 5.1 would report an attempt to push or pop a byte register as:

error A2058: Byte register illegal
Title: Re: push 0 appearing in between a function call ?
Post by: nidud on June 21, 2014, 05:56:37 AM
deleted
Title: Re: push 0 appearing in between a function call ?
Post by: jj2007 on June 21, 2014, 09:42:16 AM
Quote from: nidud on June 21, 2014, 05:56:37 AM
It's also possible to use an unaligned stack to some extent
;)
include \masm32\include\masm32rt.inc
.code
start:   
  push ax
  MsgBox 0, "Hello World", "Wow...", MB_OK
  pop ax
  exit
end start
Title: Re: push 0 appearing in between a function call ?
Post by: MichaelW on June 21, 2014, 07:48:51 PM
For 16-bit operands, since the processor knows what the operand size and stack-address size are, it sign or zero extends the operand as necessary.


;----------------------------------------
; 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

include \masm32\include\masm32rt.inc
.code
start:

  mov ebx, esp
  push ax
  mov esi, esp
  pop ax
  mov edi, esp
  printf("%d\t%d\t%d\n",alignment(ebx),alignment(esi),alignment(edi))

  mov ebx, esp
  push ds
  mov esi, esp
  pop ds
  mov edi, esp
  printf("%d\t%d\t%d\n\n",alignment(ebx),alignment(esi),alignment(edi))

  inkey
  exit
end start


4       4       4
4       4       4

Title: Re: push 0 appearing in between a function call ?
Post by: Gunther on June 21, 2014, 07:56:58 PM
Jochen,

your example works well under Windows 7 - 32 and 64 bit.

Gunther
Title: Re: push 0 appearing in between a function call ?
Post by: jj2007 on June 21, 2014, 08:21:38 PM
Quote from: Gunther on June 21, 2014, 07:56:58 PM
your example works well under Windows 7 - 32 and 64 bit.

Under Windows XP it shows a very strange box. So they "fixed" that problem, in order to ensure that lousy coders have something to chase in their sleepless nights :biggrin:
Title: Re: push 0 appearing in between a function call ?
Post by: nidud on June 21, 2014, 09:25:28 PM
deleted
Title: Re: push 0 appearing in between a function call ?
Post by: Gunther on June 22, 2014, 12:36:52 AM
Jochen,

I've tested it with Win XP as virtual machine and it works well.

Gunther
Title: Re: push 0 appearing in between a function call ?
Post by: nidud on June 22, 2014, 02:18:55 AM
deleted
Title: Re: push 0 appearing in between a function call ?
Post by: dedndave on June 22, 2014, 02:28:55 AM
masm behaves differently for PUSH and INVOKE
Title: Re: push 0 appearing in between a function call ?
Post by: Gunther on June 22, 2014, 02:45:52 AM
Dave,

Quote from: dedndave on June 22, 2014, 02:28:55 AM
masm behaves differently for PUSH and INVOKE

Are you sure?

Gunther
Title: Re: push 0 appearing in between a function call ?
Post by: dedndave on June 22, 2014, 03:30:34 AM
well - versions 6.14 and 6.15 seem to - lol
otherwise, we wouldn't be having this discussion
Title: Re: push 0 appearing in between a function call ?
Post by: MichaelW on June 22, 2014, 03:50:43 AM
Quote from: nidud on June 22, 2014, 02:18:55 AM
Quote from: MichaelW on June 21, 2014, 07:48:51 PM
For 16-bit operands, since the processor knows what the operand size and stack-address size are, it sign or zero extends the operand as necessary.
I don't think that's correct, at least not on my machine

On further examination it is correct for segment registers only, and my alignment macro is apparently broken, or at least for the way I used it.
Title: Re: push 0 appearing in between a function call ?
Post by: jj2007 on June 22, 2014, 04:04:49 AM
Quote from: Gunther on June 22, 2014, 12:36:52 AM
I've tested it with Win XP as virtual machine and it works well.

Interesting. This is what I see on XP SP3 (and whenever I see it, I know it's the stack...)
Title: Re: push 0 appearing in between a function call ?
Post by: nidud on June 22, 2014, 09:12:05 PM
deleted
Title: Re: push 0 appearing in between a function call ?
Post by: MichaelW on June 22, 2014, 10:59:59 PM
Quote from: nidud on June 22, 2014, 09:12:05 PM
I think the macro works but the result is probably overwritten.

Yes, and the only reasonable fix I can see ATM is to add a register parameter, so a unique register can be specified for each invocation.

QuoteMaybe Will was right, that they actually are 32-bit...

In 32-bit code when you push a segment register the processor zero-extends the value to 32 bits and pushes that, see the Intel documentation. I can't see any good reason for Intel not doing the same for the other 16-bit registers, but with sign-extension instead of zero-extension.