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
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
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:
that's an official bug, then
it should burp, "Invalid argument size", or something of that nature
it's already on the list of known masm bugs - same for BYTE argument, as well
Dave,
Which version of MASM?
Dave.
it seems to be 6.14 and 6.15, at least
Andreas (Japheth) keeps a list, i guess
MASM bug = MASM feature you have not adapted to. :biggrin:
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
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
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
ragdog....
try defining one of those as a WORD
.data
fhandle dd ?
pmem dw ?
nsize dd ?
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.
Thanks Dave
But i think is not really a bug by Masm only by the user
well - the bug is: masm should report an error in argument size
or maintain stack alignment, somehow
MASM 5.1 would report an attempt to push or pop a byte register as:
error A2058: Byte register illegal
deleted
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
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
Jochen,
your example works well under Windows 7 - 32 and 64 bit.
Gunther
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:
deleted
Jochen,
I've tested it with Win XP as virtual machine and it works well.
Gunther
deleted
masm behaves differently for PUSH and INVOKE
Dave,
Quote from: dedndave on June 22, 2014, 02:28:55 AM
masm behaves differently for PUSH and INVOKE
Are you sure?
Gunther
well - versions 6.14 and 6.15 seem to - lol
otherwise, we wouldn't be having this discussion
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.
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...)
deleted
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.