CS:APP深入理解计算机系统-第二章(2.1)

CS:APP深入理解计算机系统-第二章(2.1),第1张

CS:APP/深入理解计算机系统-第二章(2.1)

学习本章的意义可以用这么一句话概括:

to write programs that work correctly over the full range of numeric values and that are portable across different combinations of machine, operating system, and compiler.

2.1 Information Storage

计算机使用1个byte或者8个bit作为最小的可寻址内存单元。一个machine-level的程序将内存看作一个非常大的字节数组,叫做虚拟内存。内存中的每一个字节都由一个唯一的数字来表示,这个数字就是地址,所有地址的集合就是虚拟地址空间。既然是虚拟的,这个空间实际上只是一个概念。实际是利用DRAM、闪存等硬件和 *** 作系统软件一起实现的。

在后续的章节中,我们将会学习编译器和run-time系统如何把内存空间划分为更易于管理的单元,以存储不同的程序对象(程序数据、指令和控制信息)。各种机制被用于分配和管理程序不同部分的存储。这些管理都是在虚拟地址空间中执行的。例如,C语言中指针的值就是某个存储块的第一个字节的虚拟地址,不管这个指针是是想int、strcut还是别的什么。C语言的编译器把类型信息与每个指针关联起来,这样就可以生成不同的机器级代码来访问存储在指针指定位置的值,该位置取决于该值的类型。尽管C编译器维护这种类型信息,但实际的machine-level程序没有关于数据类型的信息,只是将每个程序对象视作一个字节块,将程序本身视作一个字节序列。

2.1.1 Hexadecimal Notation(16进制计数法)

8bit可以表示的二进制范围是00000000~11111111,如果看作是十进制整数,那就是0~255。这两种表示法都不太行,二进制太长,十进制与bit之间转换很繁琐。所以现在使用16进制(hex)。在16进制的描述下,一个byte的范围是00~FF。

在C里,以0x开头的数字通常用16进制去理解。2进制-10进制-16进制之间的对应表如下,对各位搞计算机的来说应该是小菜一碟

书里介绍了一种2进制速转16进制的方法,仅适用于2的整数次幂。假设是n次幂,那么把n拆分成i+4j的形式,其中0≤i≤3。如果是2^11,那么11=3+4*2,i=3,相应的16进制第一个数就是8,后面j=2,说明8后面跟两个0,得到16进制数0x800。可以看到i和16进制第一个数之间是由对应关系的,具体的,i=0对应1,i=1对应2,i=2对应4,i=3对应8。

书里介绍了一种10进制转16进制的方法,就是疯狂除16,得到商再除16,最后把整个过程得到的余数倒叙排列就得到结果。

书里介绍了一种16进制转10进制的方法,就是16进制的各位数乘相应的16的幂次再累加。

2.1.2 Data Size

每个计算机都有一个word size,指明指针数据的标称大小。由于虚拟地址是用这个word编码的,所以word的大小决定了虚拟地址空间的大小。举个例子,word是wbit的,那么虚拟地址的范围就是0~2^w-1,程序最多访问2^w个字节。

这就是为什么从32bit的word size扩展到64bit的word size,这样是把虚拟地址空间从4x10^9扩展到1.84x10^19byte。

在linux上用32bit编译的命令:gcc -m32 prog.c;用64bit编译的命令:gcc -m64 prog.c

这样分别编译得到32位的程序和64位的程序。

以C程序为例,C会提供多种大小的数据

 程序员应该使自己写的程序能够在不同的机器和编译器之间移植。可移植性的一个方面是使程序对不同数据类型的确切大小不敏感。C语言对不同数据类型设置了数字范围的下界,但没有给出上界。在32->64的过渡过程里,会出现一些问题。举个例子,很多人都会证明一个int去存储指针,对于32位程序,这没问题,但64位程序就会出现一些问题。

 2.1.3 Addressing and Byte Ordering(寻址和字节排序)

对于跨越多个字节的程序对象,必须建立两个约定,即确定对象的地址是什么,以及如何在内存中排列字节。在几乎所有机器中,多字节对象被存储为一个连续的字节序列,对象的地址由所使用的字节的最小地址给出。举个例子,假设有个int类型,大小4byte,地址是0x100,那么这个东西占据的内存是0x100、0x101、0x102、0x103。

对于表示对象的字节排序,有两个常见约定。考虑一个具有位表示形式的w-bit的整数[Xw-1,Xw-2,..., X1, X0],Xw-1是最重要的bit,X0是最不重要的。假设w是8的倍数,那么这些bit可以分组成byte,最重要的byte有8个bit,分别是[Xw-1, Xw-2, ..., Xw-8],最不重要的是[X7, X6, ..., X0]。一些机器选择将对象按从低到高字节的顺序存储在内存内,另一些机器按从高到低字节的顺序存储在内存内。(说白了就是地址的小端和大端)假设把0x12345678这个数放在内存里,大端和小端的存放示意图如下:

 大多Intel的机器是小端模式,许多微处理芯片是双端的,表示这种芯片既可以小端也可以大端。不难考虑到可能会出现一种情况是小端模式的A给大端模式的B发送了一串信息,那么B在接受处理这个信息的时候就有问题。所以需要遵循一个约定,确定使用哪种顺序。

2.1.4 Representing String

在C语言里,字符串由以null字符结束的字符数组编码。每个字符都由一些标准编码表示,最常见的是ASCII字符编码。

2.1.5 Represeting Code

考虑下面的代码

 当在机器上编译时,生成具有以下字节表示的机器码:

 可以发现码字是不同的,不同的机器使用不同且不兼容的指令和编码。即使是运行不同 *** 作系统的相同处理器也有不同的编码约定,因此是不兼容二进制的。二进制代码很少能在不同的机器和 *** 作系统组合之间移植。

计算机系统的一个基本概念是,从机器的角度看,程序只是一个字节序列。机器没有关于原始源程序的信息,可能除了一些辅助表来帮助调试。

2.1内容忒多了也。。。。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/3970228.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-10-21
下一篇 2022-10-21

发表评论

登录后才能评论

评论列表(0条)

保存