0

I am learning assembly and reading "Computer Systems: A programmer's perspective". In Practice Problem 3.3, it says movl %eax,%rdx will generate an error. The answer keys says movl %eax,%dx Destination operand incorrect size. I am not sure if this is a typo or not, but my question is: is movl %eax,%rdx a legal instruction? I think it is moving the 32 bits in %eax with zero extension to %rdx, which will not be generated as movzql since

an instruction generating a 4-byte value with a register as the destination will fill the upper 4 bytes with zeros` (from the book).

I tried to write some C code to generate it, but I always get movslq %eax, %rdx(GCC 4.8.5 -Og). I am completely confused.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
jeffma
  • 11
  • 4
  • 3
    both operands have to have the same size. dx is 16bit , eax 32 bits. – 0___________ Jul 02 '22 at 19:18
  • 3
    The `%dx` in the answer is probably a typo and should be `%rdx` to match the question. Note that if you are using the Global Edition, its exercises and typos are filled with severe errors and should probably be ignored altogether. See https://stackoverflow.com/questions/57998998/csapp-example-uses-idivq-with-two-operands – Nate Eldredge Jul 02 '22 at 19:27
  • If you're getting `movslq`, apparently you used signed `int` instead of `unsigned` or `uint32_t`. C semantics require sign-extension when promoting a signed type to any wider type, preserving the value. So cast to unsigned first, or `long foo(unsigned x){ return x; }`. https://godbolt.org/z/YhevPfEvc – Peter Cordes Jul 02 '22 at 22:11

1 Answers1

4

The GNU assembler doesn't accept movl %eax,%rdx. It also doesn't make sense for the encoding, since mov must have a single operand size (using a prefix byte if needed), not two different sized operands.

The effect you want is achieved by movl %eax, %edx since writes to a 32-bit register always zero-extend into the corresponding 64-bit register. See Why do x86-64 instructions on 32-bit registers zero the upper part of the full 64-bit register?.

movzlq %eax, %rdx might make logical sense, but it's not supported since it would be redundant.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
  • Just to clarify, `movl %eax, %edx` is equivalent to `movzlq %eax, %rdx` so `movzlq` is redundant, right? – jeffma Jul 02 '22 at 19:43
  • @jeffma: I guess I would say that if `movzlq %eax, %rdx` did exist, it would be equivalent to `movl %eax, %edx`, which is why it does not exist. – Nate Eldredge Jul 02 '22 at 19:43
  • @jeffma: [MOVZX missing 32 bit register to 64 bit register](https://stackoverflow.com/q/51387571) goes into more detail about why no special mnemonic for that exists, because 32-bit `mov` does the job. – Peter Cordes Jul 02 '22 at 22:08