C语言--编译器扩展

345 阅读1分钟
原文链接: zhuanlan.zhihu.com

编译器扩展,即根据数据类型是否为有符号型,在把数据扩展为字节数更多的类型时,采用“符号扩展”或者“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),但对数据的不同解读导致了不同结果。