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?
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.
Thanks, Mark Jones.
Hi nomadoro,
The 32-bit Windows desing requires the alignment of stack to DWORD.
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
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.
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".
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.
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.
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.
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.
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