1.引言:
很早就耳闻csapp的大名,这学期刚好学到计组,就连顺着拜读了一下经典的csapp。不得不说,刚读完第二章就不由得感慨,不愧是神书。
自我感觉,学校学的计组主要侧重于硬件方面,太过于底层,而csapp则是从代码的角度来解释底层的运转,不需要掌握什么三态门、什么选择器等等,更加通俗易懂。不过掌握基本的硬件对以后也是有帮助的,所以计组和csapp双修才是王道(笑)。
看完第二章就迫不及待的做了datalab,怎么说呢,刚开始的linux环境调试就费了我好大功夫,之前也没接触过,从网上搜了好多教程。怎么说呢,反正就是用linux终端的时候,终端显示错误,说你没有下载什么什么的时候,一般就跟着那个提示用install adp-get XX(root前提)就行了,之前就行需要用make命令,然后终端提示没有make,需要install。
之后就正式进入到做lab的时间了。
NO.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));
这题就是很简单的实现异或运算,学过数电的基本就是so easy。我是用x^y=(x&y)|(x&y);因为没有‘|‘,所以再左右两边同时位取反两次,就可以得到只存在&和~的表达式了。
NO.2 tmin - return minimum two’s complement integer
- Legal ops: ! ~ & ^ | + << >>
- Max ops: 4
- Rating: 1
int tmin(void) {
return 1<<31;
}
这题就是很简单的求补码的最小值,32位的补码表示的范围是-2^31 ~ 2^31-1,所以此时的最小值就是最高位为1,后面都是0,只需要将1左移31位即可。
NO.3 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 y = x+1;
return !(~(x^y)|!y);
}
其实这个函数就是判断x是否为0x7fffffff,这类的题目也就是不断的尝试,不断的错误,然后不断的改正…,所以我们可以很自然的想到(当然在做的时候并不自然…)先把x加上1,加上1后就变成了0x80000000,这样是不是就舒服点了?…然后去观察。
我们这个题目要做到的就是通过一个表达式,使得当x=0x7fffffff时为最特殊的一种情况,这种情况所得的值为1。我们应该可以想到把x和y进行异或,这样就得到全是1的二进制数了,之后自然的位取反得到0,而其他数位取反肯定不为零。所以在最前面加上一个逻辑非就能实现在x为0x7fffffff返回1,其他情况返回0。然后你欣喜的去./btest,发现错误…,原因是这类特殊情况有两种可能,还有一种是当x全为1时,x和y异或也是全为1,故只需要把这种情况排除在外就可以了。那怎么排除呢,就是找这两种情况的不同点,可以发现当x全为1时,y是0,所以只需要在~(x^y)后面“|”上一个‘!y’,当y为0时,说明应该返回0。完美解决。
其实也就是在不断的错误不断的尝试中成功的。
下面是废话可以不看:
当时做完一个题就在onenote里面做一下笔记来着…
一个菜鸡在做这题的心路历程:
NO.4 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 y=0xaa+(0xaa<<8);
int z=y+(y<<16);
return !((z&x)^z);
}
此题就是判断32位的二进制数的奇数位是否全为1,如果全为1,则返回1,否则返回0。
其实思路很简单,就是得到一个32位的奇数位全为1,偶数位全为0的数z,然后再和给定的x进行“&”操作,然后再和z异或。如果x满足条件,得到z^z-为零,否则最终结果必然不为零。最后的逻辑非能使得满足条件返回1,不满足返回0。
注:但我本人在做这道题的时候根本没想到这样做,我一直沉浸在用左移后移来比较。把interge的题目除去最后一题都做完了又想了很久还是没想出来的情况下,去网上搜了,结果发现真的就是没有想到点子上咋都不行,找到那个点了其实非常简单。
NO.5 negate - return -x
- Example: negate(1) = -1.
- Legal ops: ! ~ & ^ | + << >>
- Max ops: 5
- Rating: 2
int negate(int x) {
return ~x+