Search code examples
assemblyx86-64att

Moving two bytes into the lowest portion of a register


Assuming that the register %rdi contains 8 bytes that constitute a valid address, write the x86-64 instruction to dereference this address and move two bytes into the lowest portion of %rsi.

My answer is movq 2(%rdi), %rsi, but it's not correct.

I don't really understand how to express the "moving two bytes" part. I hope someone can explain this for me. Thanks a lot


Solution

  • move 2 bytes = word operand-size. movw (%rdi), %si.

    Or just let the assembler infer the operand size from the register, mov (%rdi), %si. Those assemble to identical machine code (which is what matters), just different ways of writing it.

    Writing to ESI would zero-extend into the full RSI, but writing to the low byte (SIL) or word (SI) leaves the upper bytes unmodified. (i.e. merges some bytes into RSI.) The reason for this difference is different choices made by 386 vs. AMD64 architects when extending x86 with wider regs. Why do x86-64 instructions on 32-bit registers zero the upper part of the full 64-bit register?

    The point of this assignment appears to be to make sure you understand how partial registers alias onto RSI.

    In real life, normally you'd want to do movzwl (%rdi), %esi to do a normal zero-extending load with no dependency on the old value, instead of a merge with the old value.