Is "push 0" treated as pushing a dword or a word or a byte?

Started by vraifreud, October 08, 2007, 12:54:40 PM

Previous topic - Next topic

vraifreud

It seems that "push 0" is treated as pushing a dword. Then what should I do if I want to push a word or byte immediate number?

Mark Jones

Hello nomadoro. In Win32, it is not possible to directly push a byte, only words and dwords. To push a word, use "pushw" instead of "push." Pushw was introduced with the 186 architecture and used extensively in DOS programming.

If you really wanted to push only one byte, then you could do something like:

        movzx ax,byte ptr [MyByteInMemory] ; or even
        mov ax,123
        pushw ax


But of course this would push your byte and a null byte.
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08


Vortex

Hi nomadoro,

The 32-bit Windows desing requires the alignment of stack to DWORD.

drizz

Warning! BUG BUG

don't use pushw with registers (immediates are OK) if your ML version is bellow 8.0,
and don't use invoke arguments with word/byte registers/variables - Masm will not extend them correctly (immediates are OK).

use movsx/movzx and push dword registers.

edit: oh, and btw pushw is pseudo instruction which translates to push with prefix
The truth cannot be learned ... it can only be recognized.

Specula

nomadoro + others, push can send a byte to memory, but pop can't.  Is this the problem, nomadoro is pushing a byte value and getting back a word?  I haven't programmed for yonkers so I maybe off track.

vraifreud

Originally, I was wondering why MASM indicated an error when pushing a byte such as "al". I was also wondering why there are no "popd" or "popw" corresponding to "pushd" and "pushw". Now it seems to me that "pushd" is not necessary since "push 0" is always treated as "pushd 0".

Specula

Quote from: nomadoro on October 12, 2007, 03:28:56 AM
Originally, I was wondering why MASM indicated an error when pushing a byte such as "al". I was also wondering why there are no "popd" or "popw" corresponding to "pushd" and "pushw". Now it seems to me that "pushd" is not necessary since "push 0" is always treated as "pushd 0".

Have you learnt to qualify your immediate and abstract, data?   Like ; push BYTE ptr 0    ....  should produce a 6A opcode version of push, which is push 8bit size.

Masm's syntax isn't always directly supplied with an equivalent opcode.  It does translation at compile time.

There's no pop 8bit from what I recall, only pop 16bit upward.  You might be able to manipulate the SP to give the effect of a pop 8bit.

hutch--

There is a simple solution to this basic question, look at the available opcodes to see what you actually CAN do. The following is from the Intel PIV manual.


PUSH—Push Word or Doubleword Onto the Stack

Opcode Instruction Description

FF /6 PUSH r/m16 Push r/m16
FF /6 PUSH r/m32 Push r/m32
50+rw PUSH r16 Push r16
50+rd PUSH r32 Push r32
6A PUSH imm8 Push imm8
68 PUSH imm16 Push imm16
68 PUSH imm32 Push imm32
0E PUSH CS Push CS
16 PUSH SS Push SS
1E PUSH DS Push DS
06 PUSH ES Push ES
0F A0 PUSH FS Push FS
0F A8 PUSH GS Push GS


Forget trying to push a BYTE, it simply does not have a corresponding opcode to do it.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

tenkey

And to avoid confusion, the PUSH imm8 does not push a BYTE. It takes the BYTE operand, expands it to WORD or DWORD, and stores the expanded WORD or DWORD data.
A programming language is low level when its programs require attention to the irrelevant.
Alan Perlis, Epigram #8

Specula

Quote from: tenkey on October 13, 2007, 06:07:15 PM
And to avoid confusion, the PUSH imm8 does not push a BYTE. It takes the BYTE operand, expands it to WORD or DWORD, and stores the expanded WORD or DWORD data.

It would still push the byte but the sp will dec the size of itself, doesn't it?  I'll have to do some experiments.

MichaelW


push -1
mov edi, [esp]
print uhex$(edi),13,10
pop eax
print ustr$(esp),13,10
push 0
mov edi, [esp]
print ustr$(esp),13,10
print uhex$(edi),13,10


FFFFFFFF
1245116
1245112
00000000
eschew obfuscation