1、计算机组成实验实验 1:实验题目:datalab-handout实验目的:根据 bits.c 中的要求补全其中的函数,并根据 README 中的要求在 linux环境下检测函数是否符合要求。实验环境:Ubuntu14.04 x86 系统实验内容及操作步骤:int bitAnd(int x, int y) return (x)|(y);运用了德摩定律,(x)|(y)= ( (x)(1n)n)即为将 x 算术右移 n 位后并上 mask 这个前 n 位为 0 的掩码,使当 x 为负数时位移补 1 换为补 0。int bitCount(int x) int result;int tmp_mask1=
2、(0x55)|(0x551)result=(resultresult=(result+(result4)result=(result+(result8)result=(result+(result16)return result;本题采用二分法,先计算 x 每两位中 1 的个数,并用对应的两位来储存这个个数。然后计算每四位 1 的个数,再用对应的四位进行储存。依次类推,最后整合得到 16 位中 1 的个数,即为 x 中 1 的个数并输出。int bang(int x) return (x|(x+1)31)(x|(x+1)即当 x 为 0 时,结果为(000) 2(31 个 0)。其余情况最首位
3、均为 1。因此右移 31 位后再取反只有 x=0 时最后一位为 1。再shiftNumber=n+33 即为-1-n+33=32-n,(xshiftNumber)即先左移 32-n 位,再右移 32-n 位,即保留最后 n 位数。在与 x 按位异或并逻辑取反,若两者两同即 x 可被表示为一个 n 位整数,结果为!0,即返回为 1。两者不同则不可表示为 n 位整数,结果为!(一个非零数),返回 0。int divpwr2(int x, int n) int signx=x31;int mask=(1n;signx=x31 为取 x 的符号位,mask=(1n 当 x 为正数即 xn,得到结果符合
4、要求。当 x 为负数时,需要加上偏置量 2n-1得到预期结果,因此加上 signx,得到结果符合要求。int negate(int x) return x+1;x+1 即 -1-x+1=-x。得到结果正确。int isPositive(int x) return !(x31)|(!x);/return (x31) /判断符号int signy=y31; int signSame=(x+(y)31)|(!(signxsigny); /判断是否小于等于int signDiffer=signx return signDiffer|signSame;int sx=!(x31); /判断符号int sy
5、=!(y31);int z=y+(x+1); /y-xint s=!(z31);return (!(sxsy)/* int difference=(x+1)+y; /*y-x*/return (x /*通过x,y,difference的卡诺图求解*/*/补码=反码 +1前两步取 x、y 的符号位,第三步中(x+(y)31 为当 x-y-1 为负数时取1,!(signxsigny)为两者相同时取 1,两者相或即 x0 时 signDiffer 为 1。最后一步即当 x0 时必返回 1,其余情况则x16)(bitsNumber+8)(bitsNumber+4)(bitsNumber+2)(bits
6、Numbel47 r+1);bitsNumber=bitsNumber+(!bitsNumber)+(0)+(!(1x);return bitsNumber;/* int ilog2(int x) x=x1; /*通过计算把1右移到的次数来实现ilog2的函数*/x=x|x1;x=x|x2;x=x|x4;x=x|x8;x=x|x16; /* 利用或和右移,把1后的所有0变为1*/int count=0;int n=0x1|0x11count+=x2count+=x3count+=x4count+=x5count+=x6count+=x7return (count /* 即BitCount函数
7、*/*/本题与 bitcout 的方法相似,也为二分法。bitsNumber=(!(x16)(bitsNumber+8)(bitsNumber+4)(bitsNumber+2)(bitsNumber+1);为判断从高到底各位的 log 情况,这个方法将每位分开求 log 并相加。bitsNumber=bitsNumber+(!bitsNumber)+(0)+(!(1x);这一句是当 x 为零时,还需要减去 1 才能得到正确的数值。unsigned float_neg(unsigned uf) unsigned result;unsigned tmp;tmp=ufresult=uf0x80000
8、000;if(tmp0x7f800000)result=uf;return result;tmp=uf0x7f800000即无穷大,如果tmp的值比无穷大还大,那就是NAN,则返回uf。unsigned float_i2f(int x) unsigned shiftLeft=0;unsigned afterShift, tmp, flag; /定义尾数,进位数unsigned absX=x; /unsigned sign=0;if (x=0) return 0;if (x0x0100)flag=1;else if (afterShift elseflag=0;return sign + (af
9、terShift9) + (159-shiftLeft)23) + flag;本题没有理解,都是用的网上的代码。unsigned float_twice(unsigned uf) unsigned f=uf;if (f else if (f return f;第一个if语句判断非规格化的数。其中(f&0x007FFFFF)1作用为令符号位和阶码被屏蔽,令尾数左移。(0x80000000 & f)是将符号位恢复。第二个else if语句判断即为规格化数。f=f+0x00800000即若是规格化数,对它的阶码加1。如果都不满足的话最后会返回uf原来的值。实验结果及分析:根据检测可知,编译通过,并且具体操作步数均低于上限。符合要求。