命令 | 解释 |
---|---|
movzx | 将用0来扩展填充操作数A的余下空间。操作数B空间必须小于操作数A;如, mov al,0xFF movzx ecx,al 执行后ecx结果为000000FF |
movsx | 将用操作数B的符号位扩展填充操作数A的余下空间,如果是负数则符号位为1,如果是正数则和MOVZX功能相同,操作数B空间必须小于操作数A; 如: mov al,0xFF movsx ecx,al FF的符号位为1,执行之后ecx的值为FFFFFFFF; mov al,0x7F movsx ecx,al 7F的符号位为0,ecx的值为000000FF |
void Function()
{
char c = 0xff;
short s = c;
//汇编代码为:
//movsx ax,byte ptr [ebp-4]
//mov word ptr [ebp-8],ax
//默认为有符号数,使用movsx指令执行
//======================
unsigned char uc = 0xff;
unsigned short us = uc;
//汇编代码为:
//movzx ax,byte ptr [ebp-4]
//mov word ptr [ebp-8],ax
//定义为无符号数,使用movzx执行
}
movsx 和 movzx都是将较小的操作数复制到较大的容器中,下面是将较大的操作数复制到较小的容器中
void Function()
{
int i = 0x12345678;
short s = i; //s的值为5678
char c = i; //c的值为78
//汇编代码如下
//mov dword ptr [ebp-4],23456789h
//mov ax,word ptr [ebp-4]
//mov word ptr [ebp-8],ax
//mov cl,byte ptr [ebp-4]
//mov byte ptr [ebp-0Ch],cl
}
可以看出如果较大的操作数复制到较小的容器中会丢失部分数据
运算中如果两个容器大小不一样运算时会自动转为较大容器运算,如果有符号数和无符号数运算会转成无符号数:
void Function()
{
//大小不一样相加运算
char c = 10;
int i = 20;
printf("%d\n",c+i);
//汇编代码:
//mov byte ptr [ebp-4],0Ah
//mov dword ptr [ebp-8],14h
//movsx eax,byte ptr [ebp-4] //在这里将byte转换成了dword
//add eax,dword ptr [ebp-8]
//===========================
//有符号和无符号相加
char c = 10;
unsigned uc = 20;
printf("%d",uc+c);
}