Environment Construction

确保有一个linux系统,并已经执行过以下两条命令:
安装gcc:sudo apt-get install build-essential
安装gcc的交叉编译环境.):sudo apt-get install gcc-multilib,因为实验的程序需要以32位方式编译
在CMU的CSAPP网站上下载实验所需资料,包括**README, Writeup,Self-Study Handout,**这三部分均包含对实验的要求说明(Handout的说明在其包含的bits.c文件中由注释给出),Self-Study Handout包括用于测试的文件


Lab1: DataLab

1.bitXor(x,y)

要用~和&实现异或^,即将结果中 1-0,0-1对应的位设置为1
x&y中为1的位(bit)对应 1-1; 取反后为:0-0、0-1、1-0;
(x&y)为1的位(bit)对应 0-0; 取反后为:1-1、0-1、1-0;
两个做交集即为结果。(位向量可以表示集合,&,|,~可视为 交,并,补操作)

/*
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) ; // if regardless '+' is illegal:(~x&y) + ((x)&(~y)) or ~((x&y) + ((~x)&(~y)))
}

2.tmin

最简单的一题:000...001 --> 1000...000

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

3.isTmax(x)

这题最开始想到 Tmin的一个性质,即对二进制补码 Tmax关于加法的逆为其本身:Tmax+Tmax = 0;因此利用这个性质写出了!((~x) + (~x)),但测试结果出乎意料,加法溢出导致了未知的行为。
根据 Tmax +1 = Tmin 的性质可以得出 , 100...000 + 011...111 = 111..1111 (-1),可得出!(~x^(x+1))(^可替换为+)
处理特例-1: -1同样会产生结果1,根据 -1+1==0,Tmax+1!=0,进而!(-1+1) !=0!(Tmax+1) ==0.
所以对Tmax, x+(x+1) = x , 对-1,x+(x+1)!=x
x+(x+1) 替换原式中的第一项x,最终得出结果:!(~((x+!(x+1))^(x+1)))

/*
isTmax - returns 1 if x is the maximum, two's complement number,
and 0 otherwise
egal ops: ! ~ & ^ | +
Max ops: 10
Rating: 1
*/
int isTmax(int x) {return !(~((x+!(x+1)) ^ (x+1))) ; // !((~x) + (~x));  it should be right, the operator "!" seem to not work
}

4.allOddBits(x)

这道题没想出来,在x上shift的方式想了一个多小时,总是不能满足所有测试用例,说明在x上shift是行不通的。
用好异或即可解决:构造101...1010,再用该数提取x中的奇数位,最后再与101...1010比较

/*
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 allOdd = (0xAA << 24) + (0xAA << 16) + (0xAA << 8) + 0xAA; // 10101010..101return ! ((allOdd & x) ^ allOdd);
}

5.isAsciiDigit(x)

有点难,还是自己做出来了,主要使用了掩码提取x中的指定位,再运用前几题的经验—用异或执行比较操作。
x的最后四位,3bit 与 1,2bit不能同时为1,因而有!((x&mask2)^mask2) + (!((x&mask3)^mask3))),难点在于怎么处理好式中三部分的逻辑关系

/* * 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 mask1 = 0x3;   // 000...0011int mask2 = 0xA;   // 1010int mask3 = 0xC;   // 1100return  !( ((x>>4)^mask1) | (!((x&mask2)^mask2) + (!((x&mask3)^mask3)) ) );
}

6.conditional

比较简单,主要实现这样一个逻辑:x!=0,返回y;x=0,返回z;
涉及的操作是把x转化为0与1两个值,再把000...0001转化为111...1111

/* * conditional - same as x ? y : z *   Example: conditional(2,4,5) = 4*   Legal ops: ! ~ & ^ | + << >> *   Max ops: 16*   Rating: 3*/
int conditional(int x, int y, int z) {int  judge = !(x ^ 0x0); // x=0 -> judge=1,whereas x!=0 -> judge=0judge = (judge << 31)>>31; // 000...000 or 111...111return ((~judge)&y) | (judge&z);
}

7.isLessOrEqual(x, y)

可通过减法y-x>=0判断x<=y,由于不存在-符,所以取x关于加法的逆-x,进而变为 x+y
那么这题就涉及加法溢出,需要对x+uw y结果的三种情况的判断(negative overflow , positive overflow),变得复杂起来。
更好的想法是分析式子**y-x**并加入一个conditional操作:如果两者异号(正-负,负-正),那么结果的正负的确定的;如果两者同号(同号相减不可能溢出),则通过与Tmin相与提取符号位。

/* * 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 Tmin = 1<<31; // 100...0000int signY = Tmin & y;int signX = Tmin & x;int judge = (signY ^ signX)<<31; x = (~x)+1;return (judge&signX) | (~(judge>>31) & !((y+x)&Tmin)) ; //
}

8.logicalNeg(x)

这题要求自己实现一个 !逻辑,即输入0返回1,输入N(N!=0)返回0。一开始的出发点是:x=0,返回1;x 位向量存在为1的位,返回0。但是仅靠逻辑运算符无法实现该想法。
于是换了一个想法:先得到x的符号位signX。signx为1,说明x为负数,可以直接得到结果;sign为0,说明x即可能为0也可能为正数,那么就要利用补码加法操作会发生的positive overflow现象,即 Tmax + x ,对任意x>0均会使结果变为负数,符号位由0 -->1。(positive overflow 不同于 negative overflow,并没有产生整数溢出,因此不会导致undefined behavior)

/* * logicalNeg - implement the ! operator, using all of *              the legal operators except !*   Examples: logicalNeg(3) = 0, logi'calNeg(0) = 1*   Legal ops: ~ & ^ | + << >>*   Max ops: 12*   Rating: 4 */
int logicalNeg(int x) {int Tmin = 1<<31;int Tmax = ~Tmin;int signX = ((x&Tmin)>>31) & 0x1;return (signX^0x1) & ((((x + Tmax)>>31)&0x1)^0x1);
}

9.howManyBits(x)

这题一开始想的是去除符号位后,找位向量中最左边的1的位置序号,但是我忽略了补码的一个性质:当数的符号位为1时,将数按符号位扩展之后其值不会变,如1101与101表示的是同一个值(-3),因此找到最左边的1并不能得到最短的位数。
要找到能表示负数的最短位数,而又不受符号位拓展的影响,便要找最左边的0,而不是1。为与对正数的操作相统一,做法是把负数按位取反(Such as: 1101 -> 0010)
按二分法逐步缩小范围,找到最左边的1

/* howManyBits - return the minimum number of bits required to represent x in*             two's complement*  Examples: howManyBits(12) = 5*            howManyBits(298) = 10*            howManyBits(-5) = 4*            howManyBits(0)  = 1*            howManyBits(-1) = 1*            howManyBits(0x80000000) = 32*  Legal ops: ! ~ & ^ | + << >>*  Max ops: 90*  Rating: 4*/
int howManyBits(int x) {int b16,b8,b4,b2,b1,b0;int signX = x>>31;x = ((~signX) & x) | (signX&(~x));// if x is negative, let sign bit:1-> 0b16 = (!!(x>>16))<<4; // ensure high 16 bits exist 1 or notx=x>>b16;b8 = (!!(x>>8))<<3; // ensure high 8 bits x=x>>b8;b4 = (!!(x>>4))<<2; // ensure high 4 bits x=x>>b4;  b2 = (!!(x>>2))<<1; // ensure high 2 bits x=x>>b2; b1 = !!(x>>1); // ensure 31 bits or not x = x>>b1;b0 = x;return b0+b1+b2+b4+b8+b16+1; // 1: sign bit
}

10.floatScale2(uf)

先对题目做出一点解释:传入一个unsigned类型的参数,但是函数内将它解释为一个浮点数类型,即参数的值不是参数的十进制值,而是其二进制形式表示的浮点数值(M×2E)
整体思路:用掩码分别提取sign,exponent,fraction三部分,再根据exp的值分类讨论
注意点:对normalized,f*2的2是乘在了2E;而对denormalized,是乘在了frac表示的M上,这也是为什么frac = frac <<1,这也使得denormalized能转化到normalized (smoothly)

//float
/* * floatScale2 - Return bit-level equivalent of expression 2*f for*   floating point argument f.*   Both the argument and result are passed as unsigned int's, but*   they are to be interpreted as the bit-level representation of*   single-precision floating point values.*   When argument is NaN, return argument    // revision: NaN or infinity*   Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while*   Max ops: 30*   Rating: 4*/
unsigned floatScale2(unsigned uf) {int musk_exp,musk_frac,sign,exp,frac,result;musk_exp = 0xFF << 23;musk_frac = 0x7FFFFF;exp = (uf & musk_exp)>>23;frac = uf & musk_frac;sign = 0x1<<31 & uf;result = 5;if(exp == 0xFF  ) // NaNresult = uf;else if(exp == 0x0) // denormalized{  if(frac == 0x0){if(sign)  // -0.0result = uf;else     // +0.0result = 0 ;}else{frac = frac << 1;result = sign+ (exp<<23) + frac;}}else if(exp != 0x0 && exp != 0xFF) // normalized{exp += 1;result = sign+ (exp<<23) + frac;}return result;
}

11.floatFloat2Int(uf)

浮点数类型的这几题比前面的题要轻松很多,大概是因为可用符号和结构比较充足的原因吧。
对题目的解释:返回浮点数f的int型表示,如输入12345.0 (0x4640E400), 正确输出为12345 (0x3039)
注意点:当f的值超过32bit的int类型位向量所能表示的最大值时(2^31-1),即E>31时,属于out of range

/* * floatFloat2Int - Return bit-level equivalent of expression (int) f*   for floating point argument f.*   Argument is passed as unsigned int, but*   it is to be interpreted as the bit-level representation of a*   single-precision floating point value.*   Anything out of range (including NaN and infinity) should return*   0x80000000u.*   Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while*   Max ops: 30*   Rating: 4*/int floatFloat2Int(unsigned uf) {int musk_exp,musk_frac,exp,frac,sign,E,Bias,result;musk_exp = 0xFF << 23;musk_frac = 0x7FFFFF;exp = (uf & musk_exp)>>23;frac = uf & musk_frac;sign = 0x1<<31 & uf;Bias = 127;result = 5;if(exp == 0xFF  ) // NaN or infinityresult = 0x80000000u;else if(exp == 0x0)result = 0;else if(exp != 0x0 && exp != 0xFF) // normalized{E = exp -Bias;  // bit_num of fractionif(E < 0)result = 0;else if (E>31)result = 0x80000000u;else{frac = frac>>(23-E);result = (0x1 << E) + frac ; if(sign == 0x1<<31)result = - result;}}return result;
}

12.floatPower2(x)

注意点:当2^x超过位向量所能表示的最大值(largest normalized)时,即exp 大于 254(1111 1110),属于too large

/* * floatPower2 - Return bit-level equivalent of the expression 2.0^x*   (2.0 raised to the power x) for any 32-bit integer x.**   The unsigned value that is returned should have the identical bit*   representation as the single-precision floating-point number 2.0^x.*   If the result is too small to be represented as a denorm, return*   0. If too large, return +INF.* *   Legal ops: Any integer/unsigned operations incl. ||, &&. Also if, while *   Max ops: 30 *   Rating: 4*/
unsigned floatPower2(int x) {int exp,frac,E,Bias,result;Bias = 127;result = 5;E = x;if(x<1 && x!=0)return 0;else if(x >= 0x1 || x == 0){frac = 0x0;exp = E+Bias;if(exp > 254)  // 1111 1110{exp = 0xFF;result = exp <<23+frac;         }elseresult = (exp<<23) + frac; }    return result ;
}

Consequence

make
./driver.pl

CSAPP - LAB 1 datalab相关推荐

  1. CSAPP LAB Binary bombs实验报告

    CSAPP LAB Binary bombs实验报告 文章目录 CSAPP LAB Binary bombs实验报告 更好的阅读体验 一.实验目的: 二.实验要求 三.实验内容(所修改函数代码,功能以 ...

  2. 新用户购买阿里云服务器 阿里云搭建Csapp Lab环境

    每一年的双十一,购买物品很多优惠.阿里云针对新用户也有优惠,最近在做CSAPP的实验.也蹭着自己是新用户购买了三年的阿里云服务器,本文介绍如何使用Xshell连接阿里云,及其使用docker搭建Csa ...

  3. CSAPP Lab:attacklab

    大小尾端 首先关于这个,我一直没记清楚,所以做个总结: 在裘宗燕翻译的<程序设计实践>里,这对术语并没有翻译为"大端"和小端,而是"高尾端"和&qu ...

  4. CSAPP LAB —— 0. 实验环境搭建

    本文原载于我的博客:https://ziyang.moe/article/csapplab0.html 前言 最近准备快速过一遍 CSAPP. 学 CSAPP 不做实验,就像四大名著不看红楼梦,说明这 ...

  5. mysql Illegal mix of collations (utf8_general_ci,IMPLICIT) and (utf8mb4_general_ci,COERCIBLE) fo...

    错误:"Illegal mix of collations (utf8_general_ci,IMPLICIT) and (utf8mb4_general_ci,COERCIBLE) for ...

  6. CSAPP Lab2 实验记录 ---- Bomb Lab(Phase 1 - Phase 6详细解答 + Secret Phase彩蛋解析)

    文章目录 Lab 总结博客链接 实验前提引子 实验需要指令及准备 Phase 1 Phase 2 Phase 3 Phase 4 Phase 5 Phase 6 Phase Secret(彩蛋Phas ...

  7. CSAPP: Architecture Lab

    介绍 本实验是将CSAPP家庭作业后面的几个问题组合成实验作业.在实验中,我们需要修改处理器的HCL描述来增加新的指令.修改循环策略等,修改后的处理器能够被模拟,并通过运行自动化测试检测. 在本实验中 ...

  8. CSAPP Lab3 实验记录 ---- Attack Lab(Ctarget)

    文章目录 Lab 总结博客链接 前引 实验前准备 Part I: Code Injection Attacks Test 1 Test 2 Test 3 结尾 Lab 总结博客链接 CSAPP Lab ...

  9. CSAPP Lab2 实验记录 ---- Bomb Lab(Secret Phase彩蛋解析)

    文章目录 Lab 总结博客链接 前引 Secret Phase 1.发现彩蛋出处 2.找寻Secret Phase 入口 3.剖析Phase Defused 寻觅进入彩蛋方法 4.终到Secret P ...

最新文章

  1. 元素的子元素_从暂元里取出子元素 | Stata编程
  2. CentOS 7 解决丢失 nginx.pid 1
  3. android调试是出现:Re-installation failed due to different application signatures
  4. 更强的压缩比!PostgreSQL开始支持Zstd
  5. 系统分析师和系统架构设计师难度比较_系统架构设计师,马上开课了!
  6. MySQL学习笔记——显示数据库信息
  7. Spring Boot笔记-404错误统一管理
  8. 阿里云盘内测_阿里云盘内测邀请码发放
  9. MySql 5.6.36 64位绿色版安装
  10. STM32工作笔记0066---待机唤醒实验-设备低功耗-M3H
  11. c语言数组指针题库,C语言 数组指针练习题.doc
  12. C++指针、空指针、野指针使用的一些总结
  13. MPAndroidChart 3.0——BarChart(一)
  14. 虚拟机安装专用游戏多开win7系统教程简单易懂
  15. 网易AI入选2018年杭州案例
  16. problem-1654B. Prefix Removals-codeforces
  17. C# 设置线程的默认CultureInfo
  18. 常用 EQ、NE、GT、LT、GE、LE的含义
  19. 去chrome视频广告插件
  20. ssh备考-08 SSH三大框架整合

热门文章

  1. 前端开发中常用的英语单词短语总结
  2. 大话西游手游服务器合服信息查询,大话西游手游合区查询 6月21日合区服务器列表...
  3. agm x2 android8.0,【AGMX2评测】性能:八核骁龙小钢炮_AGM X2_手机评测-中关村在线...
  4. install developing enviroment
  5. (轉貼) 用禅宗理解、软件开发的境界 (OO)
  6. 《逆袭大学——传给IT学子正能量》CSDN连载目录
  7. HCIA---对等网和TCP/IP
  8. 步进电动机速度调节和方向控制实验
  9. 无线控制需要服务器,H3C无线控制器与LDAP服务器配合进行远程Portal认证可以做么?...
  10. jar包(依赖jar 运行jar)