深入理解计算机系统(4) 第二章 信息的表示和处理(1)

目录

1.信息存储

1.1十六进制表示法

1.1.1由来

1.1.2表示

1.1.3十六进制与十进制、二进制之间的互相转换练习(略)

1.2字长

1.2.1数据大小

1.3寻址和字节顺序

1.3.1规则

1.4表示代码

1.5表示字符串

1.6布尔代数

1.7位级运算

 1.8逻辑运算

1.9移位运算

1.9.1左移

1.9.2右移


1.信息存储

计算机内所有的信息均以二进制的形式表示,也就是由值0和值1组成的序列

采用8个位的快/字节(最小可寻址的内存单位),而不是值0或值1的单个位。

程序会将存储器视为一个非常大的字节数组,称为虚拟存储器(virtual memory)。存储器的每一个字节都由唯一的数字来标识,也就是我们说的地址(address),所有可能地址的集合称为虚拟地址空间(virtual address space)

编译器和系统运行时是如何将存储器空间划分为更可管理的单元,用来存放不同的程序对象。这个后面会详细介绍。

1.1十六进制表示法

1.1.1由来

 一个字节由 8 位组成。在二进制表示法中,它的值域为 00000000——11111111;如果用十进制表示就是0——255。这两种表示法用来描述计算机中的位模式(计算机中所有二进制的0、1代码所组成的数字串)来说都不是很方便。二进制表示法太冗长,而十进制表示法与位模式的互相转化又比较麻烦。这时候 十六进制数产生了,

1.1.2表示

十六进制使用数字‘0’~‘9’,以及字符 ‘A’~'F’来表示16个可能的值。一般是 0x 或者 0X 开头。规则是:借一当十六,逢十六进一。

比如十进制数 175,我们用十六进制表示为 0xAF。

1.1.3十六进制与十进制、二进制之间的互相转换练习(略)

1.2字长

字的位数叫做字长(word size),每台计算机都有一个字长,用来指明整数和指针数据的标称大小(nominal size)。由于虚拟地址空间中的地址就是使用一个字来编码的,因此字长决定了系统的虚拟地址空间的最大大小。

字长是CPU的主要技术指标之一,指的是CPU一次能并行处理的二进制位数,字长总是8的整数倍,通常PC机的字长为16位(早期),32位,64位。

1.2.1数据大小

深入理解计算机系统(4) 第二章 信息的表示和处理(1)

注意:对于指针类型,由于指针指向的是地址,而虚拟空间的大小是由字长决定的。所以在32位系统下,指针大小为4个字节,在64位系统下,指针大小为8个字节。

系统的移植性:对于长整形( long int)以及字符指针类型(char *)来说,在32位和64位系统下的字节数是不同的

1.3寻址和字节顺序

对于跨越多个字节的程序对象来说,我们需要制定两个规则

(程序对象:指令、数据或者控制信息等,是程序当中对象的统称)

1.3.1规则

①、这个对象的地址是什么?

在几乎所有的机器上,多字节对象都被存储为连续的字节序列,对象的地址为所使用字节中最小的地址。

PS:假设一个类型为 int 的变量 x 地址为 0x100,也就是说地址表达式 &x 的值是 0x100,那么,x 的 4 个字节将被存储在存储器的 0x100,0x101,0x102,0x103的位置。

②、在存储器中如何排列这些字节?

排列方式

小端法:按照从最低有效字节到最高有效字节的顺序存储对象,也就是最低有效字节在最前面。

大端法:和小端法相反。是按照从最高有效字节到最低有效字节的顺序存储对象,也就是最高有效字节在最前面。

PS:假设 上面变量x 的低位字节值到高位字节值分别为 67,45,23,01。那么用大端法和小端法表示分别如下:

深入理解计算机系统(4) 第二章 信息的表示和处理(1)

 

由于排列字节的方式有两种,那么这就产生问题了。比如当小端法机器产生的数据被发送到大端法机器或者反方向发送的时候就会发现,接收程序里的字节成了反序。

为了避免这种情况,网络应用程序的代码编写必须遵循已建立的关于字节顺序的规则,以确保发送方机器将它的内部表示转换成网络标准,而接收方机器则将网络标准转换为它的内部表示。(第十一章)

1.4表示代码

int sum(int x, int y) {
    return x + y;
}

 机器上编译结果

深入理解计算机系统(4) 第二章 信息的表示和处理(1)

1.5表示字符串

使用ASCII码作为字符码的任何系统上都将得到相同的结果,与字符顺序和字大小规则无关。因而文本数据比二进制数据更具有平台独立性。

1.6布尔代数

 我们知道二进制值是计算机编码、存储和操作信息的核心,随着计算机的发展,围绕数值0和1的研究已经演化出了丰富的数学知识体系。而布尔代数便是乔治.布尔(George Boole)将逻辑值 True(真)和 False(假)编码为二进制0和1,用来研究逻辑推理的一门数学学科。

  对于布尔代数,我们需要知道以下几种常见的运算符:

深入理解计算机系统(4) 第二章 信息的表示和处理(1)

①、布尔运算 ~ 对应逻辑运算非。也就是取反的意思,假设 p 是0,那么~p 就是1;反之亦然。

②、布尔运算 & 对应逻辑运算与。有且只有 p 和 q 都为 1 时,p & q 才等于1。

③、布尔运算 | 对应逻辑运算或。p 和 q 只要有一个为 1,那么 p | q 都等于1。

④、布尔运算 ^ 对应逻辑运算异或。如果p、q两个值不相同,则异或结果为1。如果p、q两个值相同,异或结果为0。

  上面说的规则都是单个二进制进行运算。如果将其扩大到w位二进制。比如两个二进制[aw,aw-1...a1]和[bw,bw-1...b1],它们的四种运算则是对两者每一个相对应的位上做相应的运算。

  这里我们给个例子:假设 w=4,a=[0110],b=[1100]。那么四种运算 a&b、a|b、a^b、~b 结果分别如下:

深入理解计算机系统(4) 第二章 信息的表示和处理(1)

1.7位级运算

 C 语言是支持按位布尔运算的。也就是我们上面所讲的四种布尔运算符其实也是 C 语言所使用的。在 C 语言中,这些运算符能运用到任何 “ 整型” 的数据类型。也就是声明为 char 或者 int 的数据类型,无论它们有没有 short、long或者  unsigned。下面给出对 char 数据类型表达式求值的例子:

深入理解计算机系统(4) 第二章 信息的表示和处理(1)

 1.8逻辑运算

 C 语言中的逻辑运算符 ||、&&、! ,分别对于命题逻辑中的或、与、非。注意 逻辑运算 和 位级运算 它们的功能是有很大的区别的。

  ①、逻辑运算认为所有非 0 的参数都表示 true,只有参数 0 表示 false。它们返回 0 或 1 ,分别表示结果 false 和 true。

  ②、逻辑运算 && 和 || 有短路功能。比如对于表达式 p&&q,p||q,如果p的值可以确定整个表达式的结果,那么将不会计算q的值(q可能是一个表达式)。但是对于p & q则不同,无论p表达式的值为何,都要计算q表达式的值。

深入理解计算机系统(4) 第二章 信息的表示和处理(1)

1.9移位运算

移位运算分为左移右移。

1.9.1左移

运算符是 << ,丢弃最高位,低位补0

对于一个二进制数[aw,aw-1,...a1]来说,如果将它进行左移运算,则x << k = [aw-k,aw-k-1,...a1,0,...0]。此时相当于最高的那k位都被丢弃了,在最右端补了k个0。

1.9.2右移

运算符是 >>。右移一般机器支持两种形式,逻辑右移和算术右移。

逻辑右移:在左端补k 个0。C语言中对于无符号数据必须逻辑右移。

算术右移:在左端补 k 个最高有效位的值。

深入理解计算机系统(4) 第二章 信息的表示和处理(1)

在Java当中是有明确定义的。表达式 x>>k会将 x 算术右移 k 个位置。表达式 x>>>k 会将 x 逻辑右移 k 个位置