CSAPP 信息存储

CSAPP 信息存储,第1张

大多数计算机使用 8 位的块,或者字节,作为最小的可寻址的内存地址,而不是访问内存中单独的位。机器级程序将内存视为一个非常大的字节数组,称为虚拟内存,内存中每个字节都来自唯一的数字标识,称为它的地址,所有可能地址的集合就是虚拟内存地址空间。简而言之,这个虚拟内存地址空间只是一个展现给机器级程序的概念性映像。实际的实现包括,动态随机访问存储器,闪存,磁盘存储器,特殊硬件和 *** 作系统结合起来,为程序提供一个看上去统一的字节数组。

每台计算机都有一个字长,指明指针数据的标称大小。因为虚拟地址是以这样的一个字来编码的,所以字长决定的最重要的系统参数就是虚拟地址空间的最大大小。也就是说,对于一个字长为 w 的机器而言,虚拟地址的范围0~2的w次方,程序最多访问2 的w 次方个字节。

虚拟地址和物理内存:

字节顺序:内存中如何排列字节。排列表示一个对象有两种方法,大端法和小端法。

例:一个 8 位的整数,大端法表示内存中的排列 [ 7,6,52,1,0] ,其中 7 是最高有效位,0是最低有效位。小端法表示完全相反。某些机器在内存中按照从低到高的顺序存储对象,称为小端法。另一些机器则按照从最高到最低的字节顺序存储,称为大端法。

字节顺序产生的问题:

1)、小端产生的数据发送到大端,字里的字节变成反序

2)、当阅读表示整数数据的字节顺序时,字节顺序也很重要。

3)、当编写规避正常的类型系统的程序时。
①、布尔运算 ~ 对应逻辑运算非。也就是取反的意思,假设 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-1a1]和[bw,bw-1b1],它们的四种运算则是对两者每一个相对应的位上做相应的运算。这里我们给个例子:假设 w=4,a=[0110],b=[1100]。那么四种运算 a&b、a|b、a^b、~b 结果分别如下:

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

平时使用中常常会碰到ping不通的情况,ping不通的原因有非常多,比方路由设置问题,比方网络问题,下面列出几点原因:
 
1太心急。即网线刚插到交换机上就想Ping通网关,忽略了生成树的收敛时间。当然,较新的交换机都支持高速生成树,或者有的管理员干脆把用户port
(access port)的生成树协议关掉,问题就攻克了。
 2某些路由器port是不同意用户Ping的。
 3访问控制。无论中间跨越了多少跳,仅仅要有节点(包含端节点)对ICMP进行了过滤,Ping不通是正常的。最常见的就是防火墙的行为。
4多路由负载均衡场合。比方Ping远端目的主机,成功的reply和timed out交错出现,结果发如今网关路由器上存在两条到目的网段的路由,两条路由权重相等
,但经查一条路由存在问题。
 5网络因设备间的时延太大,造成ICMPecho报文无法在缺省时间(2秒)内收到。时延的原因有若干,比方线路(卫星网时延上下星为540毫秒),
香港server租用路由器处理时延,或路由设计不合理造成迂回路径。使用扩展Ping,添加timed
out时间,可Ping通的话就属路由时延太大问题。
 
6引入NAT的场合会造成单向Ping通。NAT能够起到隐蔽内部地址的作用,当由内Ping外时,能够Ping通是由于NAT表的映射关系存在,当由外发起Ping内网主机
时,就无从查找边界路由器的NAT表项了。
 7指定源地址的扩展Ping登陆到路由器上,Ping远程主机,当ICMP echorequest从串行广域网接口发出去的时候,路由器会指定某个IP地址作为源IP,这个IP地址
可能不是此接口的IP或这个接口根本没有IP地址。而某个下游路由器可能并没有到这个IP网段的路由,导致不能Ping通。能够采用扩展Ping,指定好源IP地址。
 8IP地址分配不连续。地址规划出现故障象是在网络中埋了地雷,地址重叠或掩码划分不连续都可能在Ping时出现故障。比方一个极端情况,A、B两台主机,
经过多跳相连,A能Ping通B的网关,并且B的网关设置正确,但A、B就是Ping不通。经查,在B的网卡上还设有第二个地址,并且这个地址与A所在的网段重叠。
ping不通的几种可能原因的更多相关文章
分析windows宿主机Ping不通linux虚拟机的其中一种情况
ping不通的情况是由于设置网络选项的时候,可以看到界面名称的选择如下(当前选择的是无线网卡驱动):
Ping 不通的原因分析
背景 简介 ping是常用的网络管理命令,ping也属于一个通信协议,是TCP/IP协议的一部分,适用于windows和linux以及unix 根据reply用来检查网络是否通畅&网络连接的速
VMWare虚拟机Bridged类型网卡ping不通的原因和解决办法
要使VM与局域网内的其他机器一个子网,VM的网卡设置使用桥接本来一直正常好好的, 突然有一天,遇到VMWare虚拟机Bridged类型网卡ping不通,设置,重启,查看VM网络设置,重装VMWare
VMware虚拟机中red hat linux ping不通宿主物理主机原因
在VMware Workstation中安装了red hat enterprise linux系统,网络使用“桥接”形式,最后出现在Windows下能够Ping通虚拟主机,而虚拟主机Ping不通Win
Linux通信1ping不通
关于为什么ping不通有很多种原因,但直接的表象就网络之间没有成功进行通讯: 在构建虚拟机和win之间的交互时,主要使用了3种网络模式: 桥接bridge VMnet0 主机host VMne
整理虚拟机和主机ping不通解决办法
检查几个方面: 1检查虚拟网卡有没有被禁用2检查虚拟机与物理机是否在一个VMNet中3检查虚拟机的IP地址与物理机对应的VMNet是否在一个网段4检查虚拟机与物理机的防火墙是否允许PING,
局域网内Ping不通
局域网ping不通, 原来不可忽视这步 通常,经常在局域网里面,为了检测网络是否顺畅,都会ping一下IP,如果网络正常,就可以上网或者远程处理其他故障但是会出现ping别人的主机
linux下ping不通问题的说明与解决(DNS配置丢失)
一出现问题的原因 最近由于linux需要使用外网,发现ping不通地址,经过一番查找分析后发现是DNS服务配置丢失,在这里有两种方法可以解决该问题 1:你可以手动修改/etc/sysconfig/
虚拟机和主机ping不通解决的方法
虚拟机和主机ping不通 一般有3种方式:NATbridged host-Only Bridged方式: 在图1中Network connection中选中第1项,即在vm ware虚拟机属性里
随机推荐
fopen(),fclose() 打开/关闭文件
打开/关闭/刷新流 1 fopen() 打开流 功能: 1)fopen()打开由 path指定的一个文件 2)fdopen()获取一个先有的文件描述符,并使一个标准的I/O流与该描述相结合此函数
[CSAPP笔记][第十二章并发编程]
第十二章 并发编程 如果逻辑控制流在时间上是重叠,那么它们就是并发的(concurrent)这种常见的现象称为并发(concurrency) 硬件异常处理程序,进程和Unix信号处理程序都是大家熟
[CSAPP笔记][第二章信息的表示和处理]
信息的表示和处理 21 信息存储 机器级程序将存储器视为一个非常大的字节数组,称为虚拟存储器 存储器的每个字节由一个唯一的数字表示,称为它的地址 所有可能地址的集合称为虚拟地址空间 211 十
iOS模拟器分辨率的问题(转载)
转载地址:>CSAPP的图示和问题中,我们很小心的把32(TMin32)位有符号最小值写作-2147483647-1,为什么我们不直接写成-2147483648或0x80000000呢不妨先打开limitsh头文件看看吧,你会发现它们也是用类似的诡异形式
ISO90:
Decimal: int | long | unsigned | long long
Hexadecimal: int | unsigned | long | unsigned long
ISO99:
Decimal: int | long | long long
Hexadecimal: int | unsigned | long | unsigned long | long long | unsigned long long
上面的表格是整形常量的数据类型表示,根据语言版本和格式(10进制和16进制),常量的数据类型会从上面表格里选择第一个最合适的类型。
因此,根据上述标准的话,我们可以得到如下结论:
ISO90: ISO 99:
常量表达式 -2147483648 0x80000000 -2147483648 0x80000000
32位 unsigned unsigned longlong unsigned
64位 long unsigned long unsigned
上面的表格是TMin32的数据类型表示。根据语言版本和格式,我们获得了这两种表达式的三种不同的数据类型,注意里面包括非负值值
因此定义signed int的最大值和最小值,采用如下方式
#defineINT_MAX 2147483647
#defineINT_MIN -INT_MAX-1
很不幸的因为二进制补码的数值表示不对称性,我们不得不在C语言中如此怪异地定义TMin,尽管要理解这点我们必须挖掘C预言标准中最阴暗的角落之一,这也有助于让我们更好的鉴识整形的数据类型和表示方法。
假如我们直接将TMin定义为-2147483648,那么在32位机器上编译这样的代码,编译器遇到型如-X的数值,它首先会确定X的数据类型,然后取X的负数。而2147483648对于int类型是在太大了,编译器就会再次尝试一种类型可以正确的表示此值。然后它就会按照第一个表格的顺序往下继续尝试类型,再假设编译器采用的标准是ISOC90,int的下一个类型是long,再下一个是unsigned,然后就发现unsigned是第一个合适的数据类型。正如我们知道的,21473648和-2147483648在32位数值上拥有同样的内存表示,这也导致此常量的数据类型是unsigned且值为2147483648。而ISOC99的情况则是按照上述规则数据类型为long long才能容纳2147483648。64位的情况因为2147483648与-2147483648可以表达为不同的内存表示,所以仍然按照规矩来此常量的数据类型为longlong值为-2147483648。
对于十六进制的的情况,常量0x80000000在32位机器上,编译器仍然是遵照类似的规则。无论是ISOC90还是ISOC99,都首先和TMax32(即0x7FFFFFFF)比较,发现较大后,得知int无法容纳本常量,接下去照着表格1就是UMax32(即0xFFFFFFFF),发现较小,就选择了unsigned作为本常量的数据类型,因此,常量0x80000000的数据类型是unsigned的,且值为0x80000000(或者说与2147483648相同)。
事情在64位机器上稍微有些不同,无论哪个语言版本,十进制表示的TMin都是数据类型long(64位长),值为-21473648,而十六进制表示的TMin则是数据类型unsigned,值为0x80000000(与2147483648相同)。
经过上述分析后,我们就可以得到表格2了,当数据类型为long或long long的时候,常量是负的,但它也就成了64位长。而当数据类型为unsigned时,此常量时正的32位长。用下面的代码就可以表示
intdcmp = (-2147483648 < 0);
inthcmp = (0x80000000 < 0);
上面代码尝试测试十进制和十六进制表示的TMin常量是否小于0。二者取决于编译器采用的语言版本以及字长,我们发现dcomp的值有时为0有时为1,也就是十进制表示的TMin有时候为正的有时候为负的,而hcomp的值一直是0,也就是十六进制表示的TMin永远为正的。这个简单写32位有符号最小值常量的任务比我们想象中要困难的多。(据我个人测试,VC2008在32位机器上,十进制的TMin会被认为是unsigned,而gcc在64位机器上,无论是C90还是C99都认为是long,而十六进制的TMin无论字长还是编译器都一致认为是unsigned)
问题1:
考虑如下代码:
intdtmin = -2147483648;
intdcomp2 = (dtmin < 0);
inthtmin = 0x80000000;
inthcomp2 = (htmin < 0);
无论我们在32位还是64位机器,语言版本是C90还是C99,始终dcomp2和hcomp2都为1,进一步直接将dtmin以及htmin和TMin比较都是相等的,解释这为何没有像之前一样对常量有微妙的区别。
2启示
对于大多数程序,因为字长和语言版本的不同导致的歧义并不会影响程序行为。不过我们现在已经可以了解为何将TMin32写成-2147483647-1可以获得更想要的结果了。因为TMax32的值2147483647本来就可以表示成int,所以没必要对其做类似的改写。
问题2:
假如我们把TMin32写成-0x7FFFFFFF-1,那么对于不同的字长和不同的语言版本,编译器是否会对TMin都确定同样的int数据类型呢?并尝试解释。
问题3:
你相要写一个有效的TMinW表达式,W是数值的long int类型的位数。因为数据类型在不同的机器上大小也不相同,你决定使用sizeof *** 作符,那么只要W是8的倍数,TMinW的表达式就呼之欲出,同时你还想来点小花招,你知道乘以8和左移3位是等效的。
你最先是这些尝试的:
/警告,下面的代码有bug/
/讲1左移8sizeof(long)-1位/
1L<< sizeof(long) << 3 -1;
你把这段代码在32位机器上测试,发现结果为64
A解释这是为什么
B同样的代码在64位机器上结果是多少
C做尽可能少的修改让其正确运作
如果懒得看我就简短说一下大意,为什么要特意把32位int的最小值常量写成-2147483647-1而不是-2147483648是因为编译器遇到-X这样的常量是先获得X的值与类型,然后再对其取负,而对于32位以上机器的所有int类型都容不下2147483648这么大,所以会再寻找更合适的数据类型来表示,而寻找合适类型这步在不同的C语言版本,不同的平台,不同的表示格式都有不同的适配顺序,这就导致了如果直接写-2147483648可能会是unsigned的,可能会是long还可能会是long long型的,故用-2147483647-1的形式来消弭此歧义。
问题的解答也没什么好说的,第一个其实就是最后来了步隐式转换,不管常量是什么类型,转化为int后那始终是-2147483648的字面值。第二题的原理就是-2147483647-1一样,自然是正确的。第三题只要改写成1L<< (sizeof(long) << 3 )-1; 即可,运算符优先级的问题。
发现自己正在走职业道路的下坡路,没有别的取巧方法,还是得从基础下手,提高关注度,从bit级别认识程序。
文章知识点与官方知识档案匹配
C技能树首页概览
111722 人正在系统学习中
点击阅读全文
打开CSDN,阅读体验更佳
TM4C1294主振荡器验证失效(MOSC失效)_text_in的博客
TM4C1294NCPDT微控制器提供了一个主振荡器校验电路。如果振荡器运行得太快或太慢,该电路会产生一个错误条件。如果主振荡器校验电路被启用并产生一个错误,此时会产生一个上电复位并将控制权交给 NMI处理程序,或产生中断。MOSCCTL寄存器
C语言中补码的整数运算特性_RMSnow的博客
证明:假设B2T ([11···1]) 共有w位,则其值为-2^(w-1) + 2^(w-2) + ··· + 2^0 根据等比数列求和公式,易证该值为-1 定理2 对于w位的补码B2T来说,其边界值Tmax与Tmin分别为:
C语言中TMin的写法
在看《深入理解计算机系统》第二版中文版时(Computer Systems A Programmer's Perspective Second Edititon),看到48页第二章网络旁注中提到:C语言中,将TMin32(32位有符号整数的最小值)写成 -2147483647-1。为什么不简单地写成 -2147483648 或者 0x80000000 书中提到是由于补码表示的不对称性和C
继续访问
TM4C129X CRC校验功能使用问题
以前在嵌入式开发中进行CRC校验一般通过软件算法实现,TM4C1294自带CRC校验单元,但坑比较多,发出来供使用时参考 CRC单元只有一个寄存器,7个字段需要配置 INIT:初始值; SIZE: 选择校验数据是8位还是32位; RESINV:输出按位取反; OBR:输出字节反转,例如B0[7:0]-->B0[0:7] BR:输入字节反转,例如B0[7:0]-->B0[0:
继续访问
深入理解计算机系统实验二datalab_super__cool的博客
tmin - return minimum two’s complement integer Legal ops: ! ~ & ^ | + << >> Max ops: 4 Rating: 1 / 思路: 补码的最最小值为100……0后面全是0 代码: inttmin(void){//最小的二进制数return1<<31;}
CSAPP:DataLab_吃着油条唱歌的博客
x = x | (x >> 4); x = x | (x >> 2); x = x | (x >> 1); return ~x & 0x1; } tmin(void): 返回int最小值,我的答案是0x80000000,参考答案为:0x1<<31
C语言中基本数据类型细节
期中计组考完后,虽然成绩惨不忍睹,但暴露了一些一直以来不懂但又没暴露出来的问题,在此总结。 补码Select the two’s complement negation of the following binary value: 00110011: 从以下选项选择00110011的two’s complement negation(不知咋翻) (a) 11001100 (b) 110011
继续访问
计算机系统学习-信息表示和处理二、整数表示
整数的表示和运算。
继续访问
CMU CSAPP datalab_StaRS in EyeS的博客
tmin 注意到最小的整数特征是最高位为1其余为0 inttmin(void){return1<<31;} 3tmax 因为没有办法用位运算,所以想到往tmin的特殊性上靠 tmin 和 0 是仅有的取反运算之后还是本身的值
CSAPP Lab1_Nava9的博客
~ & ^ | + << >> 最多运算符数量: 4 分值: 1 / int tmin(void) { return 1 << 31; } 1 2 3 4 5 6 7 8 9 10 ​ 补码最小值为0x80000000,由于我们只能用到0xFF以下的格式,故将0x01向左移位31个
最新发布 TMin - TMin是否产生溢出
而TMin的负仍为TMin,因此我认为TMin - TMin应该等同于TMin+TMin,所以自然算是产生了溢出。总结,出现这种纠结,还是对于溢出的定义理解不够深入,时,OF^SF和SF都被置为0。后,结果是:OF^SF被置为1,SF被置为0,即。)之后,OF=1,SF=0,则。的结果应该是1,所以得到了悖论。来进行判断的,因此我认为,
继续访问
c语言 in他long,CSAPP 读书笔记:C语言中TMin的写法转
1情景在CSAPP的图示和问题中,我们很小心的把32(TMin32)位有符号最小值写作-2147483647-1,为什么我们不直接写成-2147483648或0x80000000呢不妨先打开limitsh头文件看看吧,你会发现它们也是用类似的诡异形式ISO90:Decimal: int | long | unsigned | long longHexadecimal: int | u
继续访问
c语言中TMin的写法
在《CSAPP》中提到: #define INT_MAX 2147483647 #define INT_MIN (-INT_MAX -1) INT_MIN这样写的原因是: 虽然-2147483648 这个数值能够用int类型来表示,但在C语言中却没法写出对应这个数值的int类型常量。 因为按照c语言的类型推导,-2147483648被写成常量形式的时候,
继续访问
c语言里面TMin不能写成-2147483648的原因
C语言中TMin的写法
继续访问
C TMin
阅读深入理解计算机系统一书的225一节, 作者提到了TMin的写法是:-2147483647-1,而不是-2147483648 并没有说原因,网上查了下,其中一篇文章说的比较详细,并且引入了权威解释的链接。 >

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

原文地址: https://outofmemory.cn/zz/13415755.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-31
下一篇 2023-07-31

发表评论

登录后才能评论

评论列表(0条)

保存