更新历史

  • 20200911开始做这个实验
  • 20200915更新文章-题目更新到isTmax
  • 20200918更新文章-题目更新到isAsciiDigit
  • 20200927更新文章-题目更新到isLessOrEqual
  • 停止更新

该实验的目的

该实验的目的是提升对计算机基础信息的理解和操作,例如位,整数,浮动,补码等等。

搭建环境

环境的搭建很简单,我们遵循以下几个步骤即可

  • 下载VM Box,并安装ubuntu
  • 然后我们在虚拟机中更新环境,在终端中执行一下命令
//更新apt软件源
apt-get update
//安装sudo
apt-get install sudo
//安装c/c++编译环境,build-essential软件包列表内包含libc6-dev、libc-dev、gcc、g++、make、dpkg等
sudo apt-get install build-essential
//补充gcc的完整环境(gcc-multilib)
sudo apt-get install gcc-multilib
//安装gdb
sudo apt-get install gdb
  • 然后我们就可以愉快的写代码了,你可以使用VS Code

如何使用正确的姿势写代码和测试

主要是一下几个步骤:

  1. 阅读bits.c的注释,然后在代码处修改它
  2. 命令行运行./dlc -e bits.c查看自己用了多少操作符,以及是否有代码风格问题
  3. 使用终端,执行make clean && make btest编译文件
  4. 使用终端,执行./btest,检查自己是否做对了
  5. 最终运行./driver.pl获得打分

下面是对主要文件的解释:

  • bits.c:这个是题目文件,也是我们写代码的地方,同时里面包含着各种要求,做题时需要仔细查看该题的限制。
  • btest.c:测试代码的工具,编译它(使用终端make btest)我们可以获得可执行文件,执行它会对你的代码进行测试,注意每次修改完代码之后都需要重新编译btest.c上面显示了你哪些题目通过测试了,哪些题目没有通过测试,同时也给出了没有通过测试的原因。
  • dlc(data lab compiler)

实验开始

采用以下框架来记录

  • 题解(题目解读)
  • 代码(包含注释)
  • 思路
  • 对于本次实验的思考和总结

bitXor

题解:
只用~和&实现一个异或门

//1
/* * bitXor - x^y using only ~ and & *   Example: bitXor(4, 5) = 1*   Legal ops: ~ &*   Max ops: 14*   Rating: 1*/
int bitXor(int x, int y) {return 2;
}

思路:
在解这道题目的时候我首先想到的是在《编码》当中实现的异或门异或门是由三个逻辑门构成的,分别是与门或门非门构成的。如下图所示

而在这个题目当中,限制了我们使用或门,使得我们不得不自己使用与门非门组合成一个或门
然而要想实现一个或门我们就得先观察或门的关系表

Or 0 1
0 0 1
1 1 1

“对一个与门进行非操作,可以得到或门

这个其实是我对与门的关系表观察得到的,因为与门或门之间貌似是一个互补关系,或门为1的情况出现了三次,与门出现了一次,而且刚刚好与门出现的1的情况就在角落里,想象一下要是我可以旋转一下1值出现的地方,在进行非操作,那么不就可以得出一个或门了么。经过尝试,确实是可以的。演变的过程如下图
图图图图,后面补上

那么将这个过程转化为代码就是下面的样子

~(~x&~y)// | = ~(~x&~y)

然后再根据上面的分析,转化为代码

|&(~(x&y))
// 将|替换
(~(~x&~y))&(~(x&y))// 这个就是我们题目的答案了//1
/* * bitXor - x^y using only ~ and & *   Example: bitXor(4, 5) = 1*   Legal ops: ~ &*   Max ops: 14*   Rating: 1*/
int bitXor(int x, int y) {return (~(~x&~y))&(~(x&y));
}

最后贴上一张异或门的图

这道题很有意思,建议自己也去实现或门异或门
电路模拟

tmin

题解:
返回2进制的最小值

/* * tmin - return minimum two's complement integer *   Legal ops: ! ~ & ^ | + << >>*   Max ops: 4*   Rating: 1*/
int tmin(void) {return 2;}

思路:

0x8000 0000是16进制表示法,将16进制转化为二进制,我们就可以得出该答案了,即

/* * tmin - return minimum two's complement integer *   Legal ops: ! ~ & ^ | + << >>*   Max ops: 4*   Rating: 1*/
int tmin(void) {return 0x1<<31;}

isTmax

题解:
检查是否是有符号数的最大值

//2
/** isTmax - returns 1 if x is the maximum, two's complement number,*     and 0 otherwise *   Legal ops: ! ~ & ^ | +*   Max ops: 10*   Rating: 1*/
int isTmax(int x) {return 2;
}

思路:
这道题目和上一题的获取最小值有一点点小关系,我们要和最大值比较,那么肯定得获取到最大值,最大值的表示方法0x1<<31 - 1,然后我们就和输入值比较即可。但是题目是有限制的,不允许使用<<。那么我们只能换一种思路了。

机器在判断的时候,一个非零布尔值的都是true

根据上面的结论,我们需要判断给定值x判断是否为补码最大值,那么就需要经过某种特定的步骤把它转化为零。我们继续观察上图,发现最大值和最小值相加会等于一个特殊的值,即0xFFFF FFFF,用二进制表示它会是全一,取反之后就是全零

int i = x+1;// 这里我们取极端情况,当x就是最大值的时候,加一就变为最小值,看上面的图得出
x = x + i;// 最大值+最小值得到全一,0xFFFF FFFF
x = ~x;// 取反得全零。0x0000 0000
return !x;// 得到的结果是相反的,所有我们还得!一下。

然而到这里还没有结束,看上图,我们发现最后面的0xFFFF FFFF,它也是特殊情况之一,它加一等于全零了,而他本身是全一的情况,所以我们还得排除这个0xFFFF FFFF。到此我们的答案就出来了~

i = !i;// 给i取反,上面结论说了,一个非零的布尔值都是true,也就是1
x = x + i;// 所以当我们给x+i的时候,要么加0要么就加1,它就会影响到下面的结果//2
/** isTmax - returns 1 if x is the maximum, two's complement number,*     and 0 otherwise *   Legal ops: ! ~ & ^ | +*   Max ops: 10*   Rating: 1*/
int isTmax(int x) {int i = x+1;// 这里我们取极端情况,当x就是最大值的时候,加一就变为最小值,看上面的图得出x = x + i;// 最大值+最小值得到全一,0xFFFF FFFFx = ~x;// 取反得全零。0x0000 0000i = !i;// 给i取反,上面结论说了,一个非零的布尔值都是true,也就是1x = x + i;// 所以当我们给x+i的时候,要么加0要么就加1,它就会影响到下面的结果return !x;// 得到的结果是相反的,所有我们还得!一下。
}

allOddBits

题解:
判断在二进制表示中奇数位是否全为一

/* * allOddBits - return 1 if all odd-numbered bits in word set to 1*   where bits are numbered from 0 (least significant) to 31 (most significant)*   Examples allOddBits(0xFFFFFFFD) = 0, allOddBits(0xAAAAAAAA) = 1*   Legal ops: ! ~ & ^ | + << >>*   Max ops: 12*   Rating: 2*/
int allOddBits(int x) {return 2;
}

思路:
0xAA代表的是1010 1010,所以我们将8个A拼起来就行了

 * allOddBits - return 1 if all odd-numbered bits in word set to 1*   where bits are numbered from 0 (least significant) to 31 (most significant)*   Examples allOddBits(0xFFFFFFFD) = 0, allOddBits(0xAAAAAAAA) = 1*   Legal ops: ! ~ & ^ | + << >>*   Max ops: 12*   Rating: 2*/
int allOddBits(int x) {int mask = 0xAA + (0xAA<<8);mask = mask + (mask<<16);return !((mask&x)^mask)
}

isAsciiDigit

题解:
这道题目是让你判断一个数是否在一个区间(0x30-0x39)内

//3
/* * isAsciiDigit - return 1 if 0x30 <= x <= 0x39 (ASCII codes for characters '0' to '9')*   Example: isAsciiDigit(0x35) = 1.*            isAsciiDigit(0x3a) = 0.*            isAsciiDigit(0x05) = 0.*   Legal ops: ! ~ & ^ | + << >>*   Max ops: 15*   Rating: 3*/
int isAsciiDigit(int x) {return 2;
}

思路:

假如我们要判断的3-9这个区间,想要判断某个数和另外一个数的大小,简单的方法是通过减法,然后在通过正负号去判断。

上面的(3-1)是因为我们要包含3-3=0x0的情况,因为我们的题目是含有等于的。

回到我们的题目中,两个极值,或者叫边界值结合起来,它们需要共同满足图中的等式即
0x2F+(~x+1)=0x1
0x39+(~x+1)=0x0
转化为代码即

//3
/* * isAsciiDigit - return 1 if 0x30 <= x <= 0x39 (ASCII codes for characters '0' to '9')*   Example: isAsciiDigit(0x35) = 1.*            isAsciiDigit(0x3a) = 0.*            isAsciiDigit(0x05) = 0.*   Legal ops: ! ~ & ^ | + << >>*   Max ops: 15*   Rating: 3*/int isAsciiDigit(int x) {int min = 0x2F+(~x+1);int max = 0x39+(~x+1);min = !!(min >> 31);// 我们是通过符号位来判断的 所以将符合号位右移31位,同时将结果都转化为truemax = !(max >> 31);// 这个也需要将结果转化为true,这样下面我们才能通过与运算来确定我们要的结果return min & max;
}

isLessOrEqual

题解:
实现一个小于等于符

/* * isLessOrEqual - if x <= y  then return 1, else return 0 *   Example: isLessOrEqual(4,5) = 1.*   Legal ops: ! ~ & ^ | + << >>*   Max ops: 24*   Rating: 3*/
int isLessOrEqual(int x, int y) {return 2;
}

思路:
这道题是让我们实现一个一个小于等于符号,判断两个数的大小分两种情况

  • 符号位相同,通过做差,然后在通过符号位判断。
  • 符号位不相同,可以直接判断x的符号位。

第一种情况:
如果我们直接让x-y做差,那么会有三种结果

  • 差值小于零,符号位为一
  • 差值等于零,符号位为零
  • 差值大于零,符号位为零

那么这三种,是无法满足题目需求的,题目要求是小于等于,通过x-y小于和等于零时符号位是相反的。我们知道x<=y其实也等于y>=x,那么这种情况刚刚就满足第二和第三种情况,大于等于零的时候符号位是相同的。由此可以得出y+(~x+1),同时我们将右移加上,得到符号位

!(y+(~x+1)>>31)// 取非是因为我们的结果是零,题目要求返回1

第二种情况:
我们只需要判断符号位是否相同即可

x>>31 ^ y>>31;// 相同为零

两种情况结合:
两种情况结合的话我们需要用到mask,用来选择当另外一种情况成立时,把另外一种情况给消除掉。刚刚好我们的第二种情况就给我们提供了这样的条件。通过判断符号位,当符号位相同时,我们就将mask设置为全零,当符号位不相同时,设置mask为全一,即完成所有的代码。

/* * isLessOrEqual - if x <= y  then return 1, else return 0 *   Example: isLessOrEqual(4,5) = 1.*   Legal ops: ! ~ & ^ | + << >>*   Max ops: 24*   Rating: 3*/
int isLessOrEqual(int x, int y) {int test = !(y+(~x+1))>>31;// < 0,> 1,= 1int checkSign = x>>31 ^ y>>31;// equip 0int maskSign = ~(~checkSign+1);//0->1,1->0return (~maskSign&(x>>31 & 0x1))|(maskSign&test);//(x>>31 & 01)直接比较符号位
}

未完成,待续~

深入理解计算机系统(CSAPP) 实验详解:DataLab相关推荐

  1. 深入理解计算机系统(CSAPP) 实验详解:CacheLab

    近一段时间项目太忙导致没有继续,还好最近空下来一些,咱们继续冲! 更新历史 20210104开始更新 20210107完成实验一内容 本文介绍的是CSAPP书籍中的第四个lab: Cache lab. ...

  2. STM32F429第二十五篇之MCU屏实验详解

    文章目录 前言 硬件 软件 结构体 SRAM_HandleTypeDef Instance(FMC寄存器地址) Extended(拓展寄存器地址) Init(初始化变量) Lock(锁) State( ...

  3. CSAPP之详解Labs

    CSAPP-labs-RECORD 前言 读万卷书,不如行万里路.如果你读到了这本书,可千万不要错过本书的配套实验. 其中几个纵享盛名的实验,分别是: BombLab MollocLab ShellL ...

  4. 实验详解——Cobbler自动部署最小化安装

    实验详解--Cobbler自动部署最小化安装 一.实验:自动部署 二.Cobbler自动装机服务搭建步骤 1.导入epel源并加载在线安装源 2.安装Cobbler以及其相关服务软件包 3.修改cob ...

  5. 实验详解——DNS网关服务器的分离解析

    实验详解--DNS网关服务器的分离解析 一.实验图 二.要求 三.实验开始 1.网关服务器的配置 ①.新添加一块网卡,用双网卡来演示网关服务器的两个端口 ②.对两个网卡进行配置的修改 ③.重启网卡并查 ...

  6. 实验详解——DNS反向解析、DNS主服务器和从服务器的配置

    实验详解--DNS反向解析.DNS主服务器和从服务器的配置 实验一:DNS反向解析 1.安装bind 2.查找配置文件路径 3.配置/etc/named.conf主配置文件 4.修改/etc/name ...

  7. 详解FTP服务完成Linux和WIN10之间的信息传输(实验详解)

    详解FTP服务完成Linux和WIN10之间的信息传输(实验详解) 一.FTP简介 1. FTP服务--用来传输文件的协议 2.端口 3.数据连接模式 二.相关配置 1.安装FTP服务 2.设置匿名用 ...

  8. 详解 Linux环境中DHCP分配IP地址(实验详解)

    Linux中DHCP小实验详解 一.DHCP中继概述 二.DHCP在linux系统中的相关配置 1.配置DHCP服务器 2.设置全局配置参数 3.subnet网段声明 4.host主机声明 三.实验例 ...

  9. 实验详解——parted单磁盘分区并进行配额

    实验详解--parted单磁盘分区并进行配额 一.实验要求 二.实验开始 1.添加新硬盘 2.对新硬盘进行parted分区,格式设置为ext4 3.格式化分区,格式为ext4 4.设置配额方式和挂载 ...

最新文章

  1. 普度网络营销策划_普度网络营销策划-齐宁_新浪博客
  2. 狼羊菜过河问题深入学习分析——Java语言描述版
  3. 操作系统 ——进程的状态与转换
  4. 做自媒体和有没有文化没有太大关系
  5. 问题十一:用条件编译(#if…#endif)避免 main函数中测试代码在测试完成后就删除
  6. android Xmpp+openfire 消息推送 :SASL authentication failed using mechanism DIGEST-MD5
  7. 【通信】基于matlab语音信号仿真【含Matlab源码 957期】
  8. ROS实战篇(一)如何在ROS中编写自己的package?------ 以节点通信为例
  9. Android中铃声总结源码
  10. stm32学习探究:利用TB6612驱动直流电机
  11. 盘点前端开发常用的几款编辑器
  12. IDEA教育版申请流程
  13. 高效办公之高效学习技巧:艾宾浩斯遗忘曲线及学习策略分享
  14. OAuth 2.0 授权认证详解
  15. python计算纪念日相关
  16. 基于 Vue 实现 Excel 的解析与导出
  17. java poi 导入报错,Cannot get a NUMERIC value from a STRING cell
  18. 计算机研究生搞理论出来找工作,一个计算机专业研究生的迷茫
  19. ITIL学习笔记——核心流程之:容量管理
  20. 手机android的文件怎么恢复,安卓手机怎样恢复删除的文件

热门文章

  1. 数据库中对存储过程的理解
  2. SQL Prompt v5.3.0.3
  3. oracle 查看指标 tps(Transactions Per Second)
  4. 5611AH 数码管 引脚图
  5. 谐振电路及品质因数(三)
  6. 案例:FIFA2018球员数据分析
  7. 足球运动员的数据分析实战(python)
  8. Laurent(洛朗或者劳伦)多项式,泰勒展开式
  9. 现场测试安全帽检测系统win7版
  10. 建筑安全检查标准怎么计算机,建筑施工安全检查标准评分 怎么算