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 ?