4

The opcodes for both movzbw and movzbl are OF B6. I don't understand how they can be distinguished by observing the ModR/M byte. From the Intel 80386 Programmer's Reference Manual (1986):

MOVZX  ── Move with Zero-Extend

Opcode    Instruction      Clocks   Description
0F B6 /r  MOVZX r16,r/m8   3/6       Move byte to word with zero-extend
0F B6 /r  MOVZX r32,r/m8   3/6       Move byte to dword, zero-extend
0F B7 /r  MOVZX r32,r/m16  3/6       Move word to dword, zero-extend

How does the processor distinguish between and movzbw and movzbl?

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
Joe
  • 381
  • 2
  • 6
  • 13
  • 2
    As an addendum to the answers here, the 386 Reference Manual has a section about the operand and address size prefixes. http://www.logix.cz/michal/doc/i386/chp17-01.htm – Michael Petch Oct 11 '15 at 05:03

2 Answers2

4

Looks like it uses a prefix byte:

66 0f b6 c0             movzx  ax,al
0f b6 c0                movzx  eax,al
0f b7 c0                movzx  eax,ax

Edit: note, in 64-bit mode, the above is the same but there is another prefix:

48 0f b6 c0             movzx  rax,al
48 0f b7 c0             movzx  rax,ax

Note that there is no movzx rax, eax instruction.

(I'm an utter novice at this so I can't explain exactly why, I just throw code at the compiler and see if it's accepted).

o11c
  • 15,265
  • 4
  • 50
  • 75
  • 2
    because most operations on 32-bit register zero out the top 32 bits, therefore `movzx rax, eax` is not necessary. `mov eax, eax`, `and eax, eax`, `or eax, eax`... would do the trick. [Why do most x64 instructions zero the upper part of a 32 bit register](http://stackoverflow.com/q/11177137/995714), [zero out top 32 bits of 64-bit register](http://stackoverflow.com/q/21439289/995714) – phuclv Oct 11 '15 at 05:24
  • There's a `movsx r64, r/m32`, but another new opcode for `movzx r64, r32` would be a waste of limited opcode space that could be used instead for new extensions. `mov r32, r/m32` already does the job. (mov is a better choice than an ALU op, for Intel and AMD.) Using a REX prefix just for REX.W=1 is a waste of space for 8-64 and 16->64, too. An assembler that was more aggressive about using the shortest encoding for what you wrote might leave out the REX prefix for `movxz rax, dl`, like how `mov eax, [rsi + 0]` is encoded with no displacement byte (same as if you actually wrote `[rsi]`). – Peter Cordes Oct 11 '15 at 08:21
3

Have a look at the operand size prefix, 66H. It toggles the operand size between 16 and 32 bits.

Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180