1

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

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
jordan.goe
  • 87
  • 1
  • 7
  • so if rdi contains 0x12345678AABBCCDD what two bytes do you expect to land in si? start with that question then figure out how to get them there – old_timer Oct 14 '19 at 19:25
  • are you only modifying the lower portion of rsi or all 8 bytes are changing of which only two come from rdi? you will need to know that as well, yes? – old_timer Oct 14 '19 at 19:26
  • I'll give you a hint. Real mode instructions are valid in long mode applications and real mode data width is only 2 bytes. – Shift_Left Oct 14 '19 at 19:36
  • @Shift_Left: 16-bit operand-size doesn't make it a "real mode instruction". In 32 and 64 bit mode, the operand-size prefix overrides the default operand-size from 32 to 16. Other than that, sure, x86-64 long mode uses the same opcodes as protected and real modes, except for the opcodes that were removed. e.g. `push ds` and other segment regs are no longer valid opcodes in 64-bit mode. Neither is `aam` or other BCD instructions. But `mov (%di), %si` is *not* encodeable in 64-bit mode: 16-bit address size isn't available in 64-bit mode, only 64 or 32. – Peter Cordes Oct 16 '19 at 01:47

1 Answers1

3

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.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847