计算机系统笔记-信息的表示与处理

学习笔记

未完待续

深入理解计算机系统

第二章 信息的表示与处理

现代计算机存储和处理的信息是以二值信号表示的。二值信号可以很容易的表示、存储和传输。比如可以表示为导线上的高电压和低电压、顺时针和逆时针磁场。对二值信号进行存储和传输的电子电路也非常可靠,制造商可以在单独的硅片上集成数十万甚至数十亿个这样的电子电路。

二值就是0或1。计算机中把存储0或1的存储单元称为位,8个位称为1个字节。单个位不是很有用,但是如果把多个位组合在一起,再加上某种解释,我们就能表示有限集合的元素。比如字符码,可以对文档中的字母和符号进行编码

编码

指的是信息从一种形式转换为另一种形式的过程,也有称编程语言的代码为编码。

具体来说,是用预先规定的方法将文字、数字或其他对象编为数码或将信息、数据转换为规定的电脉冲信号。

解码

是编码的逆过程。

数字表示

计算机用有限数量的位来对一个数字编码,因此,当数字太大以致不能表示的时候,某些运算就会溢出。

通过研究数字的实际表示,就能够了解可以表示的值的范围与不同算术运算的属性。为了使得编写的程序可以在全部数值范围内正常运行,且具有跨越不同机器、编译器和操作系统组合的可移植性,了解这种特性是非常重要的。

信息存储

大多数计算机中用8位的块,或者字节,来作为最小的可寻址内存单位。

内存中的每个字节都由一个数字来标识,称为地址(address)。

所有可能的地址集合称为虚拟地址空间(virtual address space)。

编译器和运行时系统将存储空间划分为更可管理的单元,用来存放不同的程序对象,即程序指令、数据与控制信息。例如,C语言中指针的值一定是某个存储块的第一个字节的虚拟地址。指针可以是不同的类型,编译器维护着这个类型信息,且会生成不同的机器代码访问存储在指针所指向的位置的数据,但是其生成的实际目标程序并不包含这个类型信息。可以将程序对象视为一个字节块,将程序视为一个字节序列。真正地理解指针需要查看它们在机器级上的表示和实现。

十六进制表示

一个字节由8个位组成,共256种排列组合。如果看出十进制数,则值域是0~255。如果看出二进制数,则值域是00000000 ~ 11111111。二进制表示法太冗长,十进制与位模式的相互转化太麻烦。替代的方案是以16为基数,或叫做16进制(简写hex)。使用09,AF来表示位模式,则值域是00 ~ FF。C语言中十六进制以0x或0X开头。

二进制与十六进制相互转换

二进制与十六进制之间的相互转化很简单,因为一个十六进制数字对应4个位,比如:hex=0x1F对应的二进制数就是0001 1111。二进制转十六进制是同样的道理,如果二进制位数不是4的倍数就在其前面加0。

一个小技巧就是记住A、C、F对应的二进制位,分别是1010、1100、1111。

进制转换的特殊情况

如果十进制数x是2的n次幂,n为非负整数。则x的二进制表示就是1后面跟着n个0。x的十六进制表示可通过算式

n = i + 4 j n = i + 4 * j 推导,x的十六进制表示开头的数字就是1(i=0)、2(i=1)、4(i=2)、8(i=3),后续跟j个0。比如十进制数字 2 11 2^{11} ,其二进制表示形式就是1 0000 0000 000,其十六进制表示形式就是0x800。

十进制与十六进制相互转换

十六进制转十进制与二进制转十进制是相似的,用十六进制数x的每一位乘以16的位序减一次幂并累加即可。比如:x = 0xA4D,则x的十进制表示是 2637 = 10 1 6 3 1 + 4 1 6 2 1 + 13 1 6 1 1 2637=10*16^{3-1}+4*16^{2-1}+13*16^{1-1}

十进制转十六进制需要用除法,用16除十进制数x,得到商q和余数r,反复用16除q直到q为0。r需要一一转换为16进制表示,不过x的十六进制表示形式中r的使用次序与保存次序相反。比如:x = 579,则x的十进制需要进行以下除法:
579 = 36 16 + 3 36 = 2 16 + 4 2 = 0 16 + 2 579 = 36 *16 + 3 \\ 36 = 2 * 16 + 4\\ 2 = 0 * 16 + 2\\
则x的十六进制表示就是0x243。

字数据大小

每台计算机都有有一个字长,用以指明指针数据的标称大小

虚拟地址就是以这样的一个字来编码的,所以字长所决定的最重要的系统参数就是虚拟地址空间的大小。1980~2010年32位的计算机是主流,随后64位计算机占据了主流。32位字长限制了虚拟地址空间最大为4GB,64位字长则限制为16EB。

大多数64位计算机也可以运行32位的程序,称之为向后兼容。一个程序是32位的还是64位的取决于其是如何编译的,而不是运行程序的机器。

计算机和编译器对数字进行了多种编码。在C语言中,对整数类型的数字的编码包括:char、short、int、long,对小数类型的数字的编码包括:float、double。每一种编码都占用不同数量的位,以某种方式将每一种位模式对应到相应数值范围内的一个特定的数字。一般情况下,char占1个字节,short占2个字节,int占4个字节…,为了避免程序由于依赖这些典型值和不同编译器的奇怪行为带来的问题,C99推出了一系列占用的位的数量不随机器和编译器变化的数据类型,比如:int32_t、int64_t。

程序员应尽量保证程序的可移植性。而保证程序可移植性的一个方面就是使得程序对数值类型的确切大小不敏感。比如:32位程序的int类型可以保存一个32位计算机中的指针数据,但是将该程序放在64位计算机中运行便会出现错误。因此,应降低程序对字长的依赖。

寻址与字节顺序

对于跨越多个字节的程序对象,必须建立两个规则:一是这个对象的地址是什么,二是这个对象在内存中如何排列。这种数据对象一般在计算机中存储为连续的字节,比如:32位的整数类型int x,若x对象的地址是0x100,则其余字节的地址分别是0x101、0x102、0x103。每个字节包含8个位,所以对应2个十六进制数字。假设x的十六进制表示为0x12345678。那么0x100字节存储的是12还是78呢?事实上,都可以。如果存储12则表示该操作系统采用的字节顺序策略是高位优先,或叫大端法。否则,表示该操作系统采用的字节顺序策略是低位优先,或叫小端法

大多数Intel兼容机都只用小端法,IBM和Oracle的机器可能采用小端法也可能采用大端法,许多新式的处理器都支持双端法。ARM微处理器本身可以适配这两种模式,但是运行在其上的操作系统IOS或Android都只能运行于小端模式

事实上,一旦选择了特定的操作系统,那么字节顺序也就确定了下来。

对于大多数应用程序员而言,字节顺序是不可见的。应用程序一般也不会受到因字节顺序变化而造成的影响,但是在以下情况中需要考虑字节顺序:

  1. 不同类型的机器通过网络来传输二进制数据时,常见的问题是小端法机器产生的字节数据发送给了大端法机器,网络服务器发现字节顺序变成反的了。
  2. 阅读表示整数的字节序列。这通常发生在检查机器级程序的情况下。
  3. 编写规避正常类型系统的程序。

表示字符串

发布了14 篇原创文章 · 获赞 0 · 访问量 724

猜你喜欢

转载自blog.csdn.net/qq_38878217/article/details/104737586