I just found out that the push instruction can have an immediate byte , word , dword arguments and each of these have different opcodes. There were no examples in the book I was reading so I don't understand how the assembler differentiates between these three types. For example , if I write push 12h
how will it be interpreted by the assembler and what will actually happen on the stack?
That's up to the assembler. It may pick the opcode with the smallest operand field large enough to hold the immediate value. It may also require you to tell it which variant you want to use.
For example, NASM will assemble push 12h
into 6A 12
(push byte 12h
).
If you wanted e.g. to get the push imm16
variant you'd say push strict word 12h
(strict
is necessary if you don't want NASM to optimize the instruction into a byte push).
Note that an immediate byte push
doesn't actually push a byte onto the stack. The value will be sign-extended to at least 16 bits before being pushed (this happens during execution, not during compilation).