Why MOVZX r64, r/m8 behave like MOVZX r32, r/m8

26 Views Asked by At

Here is the code snippet

int main()
{
     unsigned long int ui64{};
     unsigned char ui8{ 0xAA };
     unsigned short ui16 { 0xBBBB};
     ui64 = ui8;
     ui64 = ui16;
}

Here is the opcodes that will need

MOVZX—Move With Zero-Extend     
                             
        0F B6 /r MOVZX r32, r/m8  RM Valid Valid 
REX.W + 0F B6 /r MOVZX r64, r/m8  RM Valid N.E.

        0F B7 /r MOVZX r32, r/m16 RM Valid Valid 
REX.W + 0F B7 /r MOVZX r64, r/m16 RM Valid N.E. 

When i run that code and check the assembly Godbolt MOVZX, it seems like using

0F B6 /r MOVZX r32, r/m8
0F B7 /r MOVZX r32, r/m16

instead of

REX.W + 0F B6 /r MOVZX r64, r/m8
REX.W + 0F B7 /r MOVZX r64, r/m16

I checked the MOVSX to find out that same situation happens in that instruction too.

code snippet

int main()
{
    long int i64{};
    char i8{ 1 };
    short i16 {2};

    i64 = i8;
    i64 = i16;
}

Here is the assembly code Godbolt MOVSX

MOVSX/MOVSXD—Move With Sign-Extension

        0F BE /r MOVSX r32, r/m8 RM Valid Valid
REX.W + 0F BE /r MOVSX r64, r/m8 RM Valid N.E

        0F BF /r MOVSX r32, r/m16 RM Valid Valid
REX.W + 0F BF /r MOVSX r64, r/m16 RM Valid N.E.

This time opcodes

REX.W + 0F BE /r MOVSX r64, r/m8 RM Valid N.E
REX.W + 0F BF /r MOVSX r64, r/m16 RM Valid N.E.

behave as i expect.

I want to know what is the reason ?

0

There are 0 best solutions below