0

Quick question regarding the Stack's push command.

The command PUSH [chr] does not work much like MOV sum, firstparam does not work as explained here.

So why does PUSH WORD PTR [chr] work?

* chr, sum & firstparam are locally allocated variables defined by me in .DATA.

Thanks in advance!

Community
  • 1
  • 1
Guy Azu
  • 61
  • 1
  • 9
  • `chr` is just a name for some memory location. How is the assembler supposed to know how many bytes you want to push if you just say `push [chr]`? By adding `word ptr` you're making it clear that you want to push 2 bytes worth of data. – Michael Mar 29 '16 at 16:16
  • I agree, but it still moves data from the memory itself to another part of the memory, like `MOV sum, firstparam`, doesn't it? The error is the same (A2070) too.. – Guy Azu Mar 29 '16 at 16:20
  • 1
    `push [chr]` is ambigous. `mov sum, firstparam` is simply incorrect because there's no such form of `mov`. That doesn't mean that there's some hard rule that says that an instruction can't both read and write memory - it's just that there aren't that many such instructions, and the ones that exist usually have an implicit source and/or destination (e.g. `push`, `pop`, `movs`). – Michael Mar 29 '16 at 16:30
  • Ah! Thanks for clarifying that out Michael. :) – Guy Azu Mar 29 '16 at 16:31
  • Another way to say the same thing: there are no instructions that take two arbitrary effective addresses for operands. The `mod/rm` encoding is designed for one register operand (3 bits) and one `r/m` operand (2 bits to encode the addressing mode (where register direct is one of the options), and 3 bits for the register, or another whole byte for addressing modes with an index register. In 64bit mode, the REX prefix provides the 4th bit for all registers involved (dest, base and index, or dest and src). So encoding was a factor in the original design decision that set this in stone. – Peter Cordes Mar 29 '16 at 16:41
  • @PeterCordes Just for my clarification: the mod/rm encoding is the encoding designed to address the operands, correct? If so do all commands follow that encoding, and if no are there more encodings involved around I could go read about? Thank you so much for the behind-the-scenes explanation. – Guy Azu Mar 29 '16 at 16:52
  • 1
    Yes, all instructions either have an implicit memory operand (like `[rsp+=8]` for `pop`), or use an effective-address encoded in a mod/rm + optional SIB byte. There is one major exception: `mov rax, m64` is the only way to load from a 64bit absolute address, not 32bit sign-extended, and it doesn't use mod/rm. See the Intel insn ref manuals (links in the [x86 tag wiki](http://stackoverflow.com/tags/masm/info)). Many one-operand instructions use the `/r` field of the mod/rm byte as extra opcode bits, e.g. to distinguish `not` from `neg` since they use the same opcode byte. – Peter Cordes Mar 29 '16 at 17:05
  • 1
    See also http://stackoverflow.com/questions/34058101/referencing-the-contents-of-a-memory-location-x86-addressing-modes/34058400#34058400 and http://stackoverflow.com/questions/19415184/load-from-a-64-bit-address-into-other-register-than-rax – Peter Cordes Mar 29 '16 at 17:06

0 Answers0