1

For example, can we do:

movl %eax,%rdx    // l means 32 bits while rdx is 64 biregister

so if we move 32 bits content of %eax to %rdx, then only the low order 32 bits of %rdx get updated?

  • 1
    related: [Why do x86-64 instructions on 32-bit registers zero the upper part of the full 64-bit register?](https://stackoverflow.com/q/11177137) / [MOVZX missing 32 bit register to 64 bit register](https://stackoverflow.com/q/51387571) – Peter Cordes Jul 08 '20 at 06:08
  • 2
    Your question has some different interpretations. Are you looking to preserve the upper bits after a mov from a smaller register to a larger one, or are you asking what happens to the upper bits after a move from a smaller to larger register? What is the behaviour you are looking for? – Michael Petch Jul 10 '20 at 06:20

2 Answers2

3

There is no direct way to write to only the low 32 bits of a 64 bit GPR, but it could be emulated by clearing the low 32 bits and bitwise OR-ing the value into it:

shr rdx, 32
shl rdx, 32
or rdx, rax  ; assumes top 32 bits of rax are zero

Or using a double precision shift and rotate:

shrd rdx, rax, 32
ror rdx, 32

Unfortunately this has a higher latency than the first version on most processors (except maybe Core2 and its direct ancestors), because (this form of) the double precision shift commonly takes 3 cycles. For typical Intel processors it has a potential benefit in some situations because it takes fewer µops overall, but on AMD Zen and Intel Atom the shrd takes a handful of µops. So in general the first version should be preferred, but in specific cases there may be a reason to use the second version.

It's also possible with two overlapping stores and a load (this is slow, for example 16 cycles on Haswell due to store-forwarding fail, and even without hitting such a bad microarchitectural edge case it would not have beaten the register-only solutions):

mov [rsp], rdx
mov [rsp], eax
mov rdx, [rsp]
harold
  • 61,398
  • 6
  • 86
  • 164
1

movl %eax,%rdx (equivalent to mov %eax,%rdx) is not a valid instruction. The valid combinations for MOV can be found in the Instruction Set Architecture reference.

There are a couple of instructions that can move from smaller registers to larger registers. You can use MOVZX for zero extension (upper bits set to 0), or MOVSX sign extension where the top most bit of the source register is copied into all the higher bits of the destination register. In 64-bit long mode if the destination of any instruction (including MOV) is a 32-bit register then the upper 32-bits of the corresponding 64-bit register are set to 0 automatically by the processor.

These examples represent valid moves available that go from smaller registers to larger registers:

movzx %al, %dx     # move 8-bit register to 16-bit register. Upper 8 bits of DX set to 0
movzx %al, %edx    # move 8-bit register to 32-bit register. Upper 24 bits of EDX set to 0
                   #     Upper 32 bits of RDX also set to zero because EDX is 32-bit dest
movzx %al, %rdx    # move 8-bit register to 64-bit register. Upper 56 bits of RDX set to 0

movzx %ax, %edx    # move 16-bit register to 32-bit register.Upper 16 bits of EDX set to 0
                   #     Upper 32 bits of RDX also set to zero because EDX is 32-bit dest

#movzx %eax, %rdx  # This instruction doesn't exist. Use mov %eax, %edx

movsx %al, %dx     # Sign extend 8-bit register to 16-bit register
movsx %al, %edx    # Sign extend 8-bit register to 32-bit register
                   #     Upper 32 bits of RDX set to ZERO because EDX is 32-bit dest
movsx %al, %rdx    # Sign extend 8-bit register to 64-bit register

movsx %ax, %edx    # Sign extend 16-bit register to 32-bit register
                   #     Upper 32 bits of RDX set to ZERO because EDX is 32-bit dest
movsx %ax, %rdx    # Sign extend 16-bit register to 64-bit register

movsx %eax, %rdx   # Sign extend 32-bit register to 64-bit register
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
  • While this is all true information, it doesn't really explain how to do what the OP wants to do. The OP wants to move `eax` into the lower half of `rdx` while preserving the upper half of `rdx`, which none of those do. – Joseph Sible-Reinstate Monica Jul 10 '20 at 05:00
  • @JosephSible-ReinstateMonica : Unless I am missing something I don't see anything in the question that states he wants to retain the info in the upper 32-bits. First of all there is the question in the title that asks about moving smaller to larger registers. In the question he did ask a further question `then only the low order 32 bits of %rdx get updated?` The answer to that is no since the instruction he is using isn't even valid. Both of those questions I address in my answer. – Michael Petch Jul 10 '20 at 06:01
  • That "further question" is what I meant. Although his example instruction is invalid, and it looks like the answer is "it's impossible in a single instruction", wouldn't it be better to say that in the answer, and to show a solution with multiple instructions? – Joseph Sible-Reinstate Monica Jul 10 '20 at 06:03
  • @JosephSible-ReinstateMonica It isn't clear that he ever intended to do that! At no point did he ask if you could store a smaller register into a larger register and retain the value in the upper portion. My answer (in the table of instructions) points out `mov %eax, %rdx` isn't valid but to do what I believe he is asking I suggested that `mov %eax, %edx` would suffice. I am basing my answer on the premise that since he never said anything about retaining the higher bits, that it is a non issue. If OP is asking for situation of retaining the higher bits then he can accept the other answer. – Michael Petch Jul 10 '20 at 06:07
  • I am answering the question I believe that the OP is asking about. But since there is uncertainty as to what the real question is they have a choice between 2 answers. That will be up to the OP. The question is ambiguous since he never established what result he actually wants. Given the question in the title I don't think he understands the basics of moving from narrow to wider registers. – Michael Petch Jul 10 '20 at 06:09
  • 1
    I agree, I rolled the dice on what OP might mean but I could just as easily have guessed wrong – harold Jul 10 '20 at 06:39