作者在 2011-04-01 23:01:22 发布以下内容
几乎所有的机器上,多字节对象都被存储为连续的字节序列,对象的地址为所使用字节中最小的地址,例如:int 型变量x的地址为0X100,即地址表达式&X的值为0X100,那么x的4个字节将被存储在存储器的0X100,0X101,0X102和0X103的位置。
考虑一个十位整数,位表示为[Xw-1,Xw-2,...,X1,X0],其中Xw-1是最高有效位。X0为最低有效位,若w是8的倍数,这些位可被分组为字节,期中最高有效字节包括位[Xw-1,Xw-2,...,Xw-8],最低有效位包括[X7,X6,...,X1,X0],其他字节包括中间的位。最低有效字节在最前面的方式为小端法,最高有效位在最前面的方式为大端法。大多数Intel兼容的机采用小端法,IBM和Sun Microsystems的机器大部分采用大端法,但是排列表示一个对象的自己诶的规则不是按照企业界限严格划分的,许多比较新的微处理器使用双端法,即可以把他们配制成作为大端或者小端的机器运行。
如果对第一个参数求值就能确定表达式的结果,那么逻辑运算的就不会对第二个参数求值。
C语言中的移位运算:对于一个位表示为[Xn-1,Xn-2,...,X0]的操作数X,C表达式x<<k;会生成一个值,其位表示为[Xn-k-1,Xn-k-2,...,X0,0,...,0],即x向左移动k位,丢弃最高位的k位,并在右端补k个0,移位量应是一个0~n-1之间的数,移位的运算是从左到右可结合的。
右移位运算x>>k;的行为有些微妙,一般而言机器支持两种形式的右移位:逻辑右移和算术右移。逻辑右移在左端补k个0,得到[0,0,...,0,Xn-1,Xn-2,...,Xk],算术右移在最左端补k个最高位有效值,得到[Xn-1,Xn-1,...,Xn-1,Xn-2,...,Xk].C语言标准没有确定应该用哪种类型的右移,对于无符号数据(用unsigned声明的正兴对象)右移必须是逻辑的。对于有符号数据,算术的和逻辑的都可以。实际上几乎所有的编译器/机器组合都对有符号数据使用算术右移。
对大多数C语言的实现而言,处理同样字长的有符号数和无符号数之间的转换的一般规则是:数值可能会改变,但是位模式不变。
当执行一个运算时,如果它的一个运算数是有符号的,而另一个是无符号的,那么C语言会隐式的将有符号参数强制转换成无符号数,并假设这两个数都是非负的,来执行这个运算。
将一个无符号数转换成一个更大的数据类型,只需要简单的在表示开头添加0,这种运算称为零扩展(zero expression);将一个补码数字转换为一个更大的数据类型,可以执行符号扩展(sign expression),规则是在表示中添加最高位有效位的值的副本,如原始值的位表示为[Xw-1,Xw-2,...,X0],扩展后的表示就为[Xw-1,...,Xw-1,Xw-1,Xw-2,...,X0].
一个算术运算的溢出是指完整的整数结果不能放到数据类型的字长限制中去。
进程是操作系统对一个正在运行的程序的一种抽象。
hello.c hello.i hello.s hello.o
-------------->预处理器(cpp)------------->编译器(ccl)-------->汇编器(as)----------->连接器
源程序(文本) 被修改的源程序 汇编程序 可重定位的目标程序
(文本) (文本) (二进制 )
hello
(ld)---------------------->
可执行的目标程序(二进制)