编译器扩展,即根据数据类型是否为有符号型,在把数据扩展为字节数更多的类型时,采用“符号扩展”或者“0扩展”。
1,符号扩展,根据最高位(符号位)来填充,为1则添1,为0则添0
2,0扩展,一律添0
例如:
char c=0x80;
unsigned char uc =0x80;
int i=c;
int i2=uc;
printf("%d,%d\n", i, i2);
输出为-128,128,即:char扩展为int 时为符号扩展,unsigned char为0扩展。
实际在底层,只有内存地址和寄存器,并不存在数据类型,而是通过不同的汇编指令来做符号扩展或0扩展。
X86系列,符号扩展的指令为movsbl,0扩展为movzbl。
上述C代码变成汇编的指令系列如下,Linux AT&T语法:
符号扩展为:
mov $0x80,%al
movsbl %al,%eax
0扩展则为:
movzbl %al,%eax
ARM系列则有LDRB,LDRSB等类似指令,加载内存单字节到32位寄存器并扩展为32位数。
就这个例子来说,数据含有的信息量是一样的(都是单字节0x80),但对数据的不同解读导致了不同结果。