You cannot pass whatever operand you can think of to assembly instructions; while the assembly syntax smooths some differences over and can make you think that any operand is admitted, in facts the same assembly instruction with different kinds of operands gets translated to different opcodes, and they are defined only for a handful of operand types combinations.
Does it mean that we can only use n(%ebp)
as a source operands?
In line of principle, it depends from the specific instruction; for most instructions, you can use a memory operand as either source or destination operand, but not both.
Look at the reference documentation for mov
¹: there's no variant that takes two memory operands (although there are variants with the memory operand as either the source or destination); you have to go through a temporary register.
As for imul
, again, look at the documentation: there's no variant with two memory operands, you have to go through a register (typically eax
, as its encoding is more compact).
- When reading the documentation, remember that rXX (XX being 8, 16, 32 or 64) means "a general purpose XX bits register", r/mXX means "a general purpose XX bits register or memory operand" and immXX means "an XX bits immediate value". Also, most documentation is in Intel syntax, so if you are used to AT&T you have to reverse the operands order.