Hi, I was wondering I have code that pushes a WORD onto the stack, but it must call some external code in VC++, I think there is a PUSH instruction that automatically extendes the WORD into a DWORD and then push it on the stack, how do I get MASM to compile it like that?
Posted on 2003-09-17 20:36:45 by x86asm
what you're probably looking for is

movzx eax, value
push eax
Posted on 2003-09-17 20:50:20 by grv575
When programming in 32-bit mode, most assemblers would push a 0 value word prior to pushing a word value to maintain proper alignment of the stack.

Raymond
Posted on 2003-09-17 22:33:15 by Raymond
In MASM and most other assemblers you can do half-stack operations but the stack is always addressed in DWORDs in 32 bit mode so you must do all half stack operations in pairs. If you neglect to do this the assembler will do it for you, I know of no assembler that does not do this. MASM however allows you to over-ride the push WORD PTR 0 by pushing your own word value instead for example:

pushw 4

will compile as

push WORD PTR 4
push WORD PTR 0

however you can override the 0 with your own value if you perform another half stack push directly afterwards:

pushw 4
pushw 8

will compile as

push WORD PTR 4
push WORD PTR 8
Posted on 2003-09-17 22:48:40 by donkey
And why is so important for 32bi processors to have everything aligned in memory on dwords?
Posted on 2003-09-18 07:42:34 by Mikky

And why is so important for 32bi processors to have everything aligned in memory on dwords?

exactly :)

It's a 32 bit processor and a DWORD is 32 bits. The processor grabs 32 bits at a time on a DWORD boundary, if the data is not on a boundary it takes two fetches. The stack is optimized for speed so it requires that everything is aligned.
Posted on 2003-09-18 07:56:43 by donkey
To understand why you need to operate in DWORDS, you need to understand the stack. Assume the -- is a "cubb hole" of memory thats 32 bits wide. Assume that << is the stack pointer, which is currently pointing at a specific address on the stack.

-- 0x000000 (0 Decimal) << This is where the stack pointer starts
-- 0x000020 (32 Decimal)
-- 0x000040 (64 Decimal)
-- 0x000060 (96 Decimal)
-- 0x000080 (128 Decimal)
-- 0x0000A0 (160 Decimal)
-- 0x0000C0 (192 Decimal)
-- 0x0000E0 (224 Decimal)
-- 0x000100 (256 Decimal)

then we push a dword (from eax)

-- 0x000000 (0 Decimal) == Whatever we pushed (eax)
-- 0x000020 (32 Decimal) << Now points here
-- 0x000040 (64 Decimal)
-- 0x000060 (96 Decimal)
-- 0x000080 (128 Decimal)
-- 0x0000A0 (160 Decimal)
-- 0x0000C0 (192 Decimal)
-- 0x0000E0 (224 Decimal)
-- 0x000100 (256 Decimal)

then we pop a dword (into ebx)

-- 0x000000 (0 Decimal) << Now points here AND ebx == eax
-- 0x000020 (32 Decimal)
-- 0x000040 (64 Decimal)
-- 0x000060 (96 Decimal)
-- 0x000080 (128 Decimal)
-- 0x0000A0 (160 Decimal)
-- 0x0000C0 (192 Decimal)
-- 0x0000E0 (224 Decimal)
-- 0x000100 (256 Decimal)

The stack actually face the other way, meaning that 0x000000 would be at the bottom, but thats really inconsequential to how it works. I might not have explained this clearly, so correct me if im wrong, im thinking of how it works, i may have just explained it wrong. Cheers!



exactly :)

It's a 32 bit processor and a DWORD is 32 bits. The processor grabs 32 bits at a time on a DWORD boundary, if the data is not on a boundary it takes two fetches. The stack is optimized for speed so it requires that everything is aligned.
Posted on 2003-09-18 18:32:20 by Snoopy2K
The processor does not have an alignment requirement for stack operations. Speed is usually the only reason for a programmer to keep it aligned. But apparently, Windows NT requires DWORD alignment and will often goof up when a system call is made with an unaligned stack.

Anyway, instead of PUSH WORD 0, you could use db 0x66,0x6a,0. It is one byte smaller.
Posted on 2003-09-19 12:56:35 by Sephiroth3
NT and simular OS want practically *every* memory object your use, or give to the OS aligned on DWORD boundries. They are very finiky in this matter from my experiences.

The Win98/ME is more relaxed. However, its a good practice to get into to be compatable with all OS's.

Regards,
:NaN:
Posted on 2003-09-19 15:11:59 by NaN
Funny, today I created proc that expects dword as parameter, but when I pass it a word it crashes on 98, but on XP it works fine.

So when 64bit processors become average desktop machine, everything will be 2*dword aligned?
And our 32bit programs will be sloppy and tend to crash like this one?
Posted on 2003-09-19 17:11:11 by Mikky
2*dword is called a QWORD or a QDWORD. But the reason it didnt run on 98, and did run on XP is the backwards compatibility features that XP has. So old progs dont hang the OS when they dont push DWORDs. Remember, there was once a day where 16+ bit OS's were less than mythical :)
Posted on 2003-09-19 17:55:21 by Snoopy2K
I dont understand what backward compatability has to do with crashing on 98 and not on XP, are you saying that w98 is 16bit OS?
:stupid:
Posted on 2003-09-20 15:34:05 by Mikky
9x is actually a mixed 32/16bit OS... sucky sucky.

Win32 programs should always use multiples-of-four when dealing with the stack, otherwise chaos will insure. However, this doesn't mean 32bit programs will crash on the 64bit processors - if the programs can run there, they will run in an emulation layer or 32bit VM - just like win16 programs run fine on NT, and (most) 16bit dos programs run fine in vm86.

It's a good idea to keep everything 4-byte aligned for speed reasons anyway. It's not like you lose a lot of bytes by doing this, and you _are_ assembly programmers in desire of speed, aren't you? Otherwise, what's the point in doing assembly? ;)
Posted on 2003-09-21 05:42:54 by f0dder