1. 程式人生 > >lab1作業系統和原理詳解

lab1作業系統和原理詳解

/* 
 * CS:APP Data Lab 
 * 
 * <Please put your name and userid here>
 * 
 * bits.c - Source file with your solutions to the Lab.
 *          This is the file you will hand in to your instructor.
 *
 * WARNING: Do not include the <stdio.h> header; it confuses the dlc
 * compiler. You can still use printf for debugging without including
 * <stdio.h>, although you might get a compiler warning. In general,
 * it's not good practice to ignore compiler warnings, but in this
 * case it's OK.  
 */

#if 0
/*
 * Instructions to Students:
 *
 * STEP 1: Read the following instructions carefully.
 */

You will provide your solution to the Data Lab by
editing the collection of functions in this source file.

INTEGER CODING RULES:
 
  Replace the "return" statement in each function with one
  or more lines of C code that implements the function. Your code 
  must conform to the following style:
 
  int Funct(arg1, arg2, ...) {
      /* brief description of how your implementation works */
      int var1 = Expr1;
      ...
      int varM = ExprM;

      varJ = ExprJ;
      ...
      varN = ExprN;
      return ExprR;
  }

  Each "Expr" is an expression using ONLY the following:
  1. Integer constants 0 through 255 (0xFF), inclusive. You are
      not allowed to use big constants such as 0xffffffff.
  2. Function arguments and local variables (no global variables).
  3. Unary integer operations ! ~
  4. Binary integer operations & ^ | + << >>
    
  Some of the problems restrict the set of allowed operators even further.
  Each "Expr" may consist of multiple operators. You are not restricted to
  one operator per line.

  You are expressly forbidden to:
  1. Use any control constructs such as if, do, while, for, switch, etc.
  2. Define or use any macros.
  3. Define any additional functions in this file.
  4. Call any functions.
  5. Use any other operations, such as &&, ||, -, or ?:
  6. Use any form of casting.
  7. Use any data type other than int.  This implies that you
     cannot use arrays, structs, or unions.

 
  You may assume that your machine:
  1. Uses 2s complement, 32-bit representations of integers.
  2. Performs right shifts arithmetically.
  3. Has unpredictable behavior when shifting an integer by more
     than the word size.

EXAMPLES OF ACCEPTABLE CODING STYLE:
  /*
   * pow2plus1 - returns 2^x + 1, where 0 <= x <= 31
   */
  int pow2plus1(int x) {
     /* exploit ability of shifts to compute powers of 2 */
     return (1 << x) + 1;
  }

  /*
   * pow2plus4 - returns 2^x + 4, where 0 <= x <= 31
   */
  int pow2plus4(int x) {
     /* exploit ability of shifts to compute powers of 2 */
     int result = (1 << x);
     result += 4;
     return result;
  }

FLOATING POINT CODING RULES

For the problems that require you to implent floating-point operations,
the coding rules are less strict.  You are allowed to use looping and
conditional control.  You are allowed to use both ints and unsigneds.
You can use arbitrary integer and unsigned constants.

You are expressly forbidden to:
  1. Define or use any macros.
  2. Define any additional functions in this file.
  3. Call any functions.
  4. Use any form of casting.
  5. Use any data type other than int or unsigned.  This means that you
     cannot use arrays, structs, or unions.
  6. Use any floating point data types, operations, or constants.


NOTES:
  1. Use the dlc (data lab checker) compiler (described in the handout) to 
     check the legality of your solutions.
  2. Each function has a maximum number of operators (! ~ & ^ | + << >>)
     that you are allowed to use for your implementation of the function. 
     The max operator count is checked by dlc. Note that '=' is not 
     counted; you may use as many of these as you want without penalty.
  3. Use the btest test harness to check your functions for correctness.
  4. Use the BDD checker to formally verify your functions
  5. The maximum number of ops for each function is given in the
     header comment for each function. If there are any inconsistencies 
     between the maximum ops in the writeup and in this file, consider
     this file the authoritative source.

/*
 * STEP 2: Modify the following functions according the coding rules.
 * 
 *   IMPORTANT. TO AVOID GRADING SURPRISES:
 *   1. Use the dlc compiler to check that your solutions conform
 *      to the coding rules.
 *   2. Use the BDD checker to formally verify that your solutions produce 
 *      the correct answers.
 */


#endif
/* Copyright (C) 1991-2014 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, see
   <http://www.gnu.org/licenses/>.  */
/* This header is separate from features.h so that the compiler can
   include it implicitly at the start of every compilation.  It must
   not itself include <features.h> or any other header that includes
   <features.h> because the implicit include comes before any feature
   test macros that may be defined in a source file before it first
   explicitly includes a system header.  GCC knows the name of this
   header in order to preinclude it.  */
/* glibc's intent is to support the IEC 559 math functionality, real
   and complex.  If the GCC (4.9 and later) predefined macros
   specifying compiler intent are available, use them to determine
   whether the overall intent is to support these features; otherwise,
   presume an older compiler has intent to support these features and
   define these macros by default.  */
/* wchar_t uses ISO/IEC 10646 (2nd ed., published 2011-03-15) /
   Unicode 6.0.  */
/* We do not support C11 <threads.h>.  */
 * absVal - absolute value of x
 *   Example: absVal(-1) = 1.
 *   You may assume -TMax <= x <= TMax
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 10
 *   Rating: 4
 */
int absVal(int x) {
int k;
k=x>>31;
  return (x^(k))+(~k+1);
}
此題要求是求int型數的絕對值,k的意思把這個數字右移31位如果是正數則返回0否則返回-1,在輸出的時候~k+1的意思1是-k,異或是相同為零不同為1,而把k和x異或 當x是正數的時候相當於x和0異或再減0 沒有影響若是x是負數的話 x與-1異或 二-1的二進位制是111111 得到(x-1)-(-1)得到x的絕對值
/* 
 * bitXor - x^y using only ~ and & 
 *   Example: bitXor(4, 5) = 1
 *   Legal ops: ~ &
 *   Max ops: 14
 *   Rating: 1
 */
int bitXor(int x, int y) {
    ~((~(x&~y))&(~(~x&y)));
  return 2;
}
此題是用~和&符號來實現異或,根據真值表來得出最後的結果
           &  ^
0 0  1  0  0   0
0 1  0  0  0   1
1 0  1  1  0   1
1 1  0  0  1   0
/*
 * bitCount - returns count of number of 1's in word
 *   Examples: bitCount(5) = 2, bitCount(7) = 3
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 40
 *   Rating: 4
 */
int bitCount(int x) {
  //資料結構習題解析第三版 鄧俊輝 第一章 12題(b) Page 9
  /*
   * Warning: 42 operators exceeds max of 40
   *
  int mask0 = (0x55) | (0x55 << 8) | (0x55 << 16) | (0x55 << 24);  //0x55555555
  int mask1 = (0x33) | (0x33 << 8) | (0x33 << 16) | (0x33 << 24);  //0x33333333
  int mask2 = (0x0F) | (0x0F << 8) | (0x0F << 16) | (0x0F << 24);  //0x0F0F0F0F
  int mask3 = (0xFF) |               (0xFF << 16);                 //0x00FF00FF
  int mask4 = (0xFF) | (0xFF << 8);                                //0x0000FFFF
  */

  int a = (0x55) | (0x55 << 8);
  int mask0 = a | (a << 16);
  int b = (0x33) | (0x33 << 8);
  int mask1 = b | (b << 16);
  int c = (0x0F) | (0x0F << 8);
  int mask2 = c | (c << 16);
  int mask3 = (0xFF) | (0xFF << 16);
  int mask4 = (0xFF) | (0xFF << 8);

  //unsigned int n = (unsigned int)x;
  int n = x;
  n = (n & mask0) + (n >> 0x01  & mask0);
  n = (n & mask1) + (n >> 0x02  & mask1);
  n = (n & mask2) + (n >> 0x04  & mask2);
  n = (n & mask3) + (n >> 0x08  & mask3);
  n = (n & mask4) + (n >> 0x10  & mask4);

  return n;
}
/* 
 * byteSwap - swaps the nth byte and the mth byte
 *  Examples: byteSwap(0x 12 34 56 78, 1, 3) = 0x56341278
 *            byteSwap(0xDE AD BE EF, 0, 2) = 0xDE EF BE AD
 *  You may assume that 0 <= n <= 3, 0 <= m <= 3
 *  Legal ops: ! ~ & ^ | + << >>
 *  Max ops: 25
 *  Rating: 2
 */
int byteSwap(int x, int n, int m) {
Int n1=n<<3;
Int m1=m<<3;
Int chaneg1,change2,locate;
Change1=(((x>>n1)&0xFF)<<m1);
Change2=(((x>>m1)&0xFF<<n1);
Locate=(x&(~(0xFF<<n1))&(0xFF<<m1));
    return change1|change2|locate;
}
因為16進位制下8位元才等於一位元組也就是每兩個字母等於一個位元組,所以每次要改變的要乘以八倍,change1是為了把x在n位置的位元組移動到m位元組上並且除了m位元組其他全為0,change2是為了把x在m位置的位元組移動到m位元組上並且除了n位元組其他全為0,locate是為了求出x除了n,m位元組的其他位元組,最後相或從而實現換位
/* 
 * oddBits - return word with all odd-numbered bits set to 1
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 8
 *   Rating: 2
 */


int oddBits(void) {
Int x=1;
Int y=-1;
1010101010  return 2;
}
因為10的二進位制碼為1010所以不斷左移並相加得到32位的該數
/* 
 * isLess - if x < y  then return 1, else return 0 
 *   Example: isLess(4,5) = 1.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 24
 *   Rating: 3
 */

int isLess(int x,int y)
{
Int x1=x>>31;
Int y1=y>>31;
Int judge1=(!(x1^y1));
Int judge2=(x1&(!y1));
Int first=(!((y+~x)>>31));
Int middle=judge1&first;
Int ans=middle|judge2;
Return ans;
}
//(!(sx^sy))
//+ - 0
//- + 0
//+ + 1
//- - 1
//=== 0
//                  (!(sx^sy))    !((y+~x+1)>>31)           (sx&(!sy))
//+   -  0               0           0             0              0       0
//-   +  1               0           1             0              1       1
//6   5  0               1           0             0              0       0
//5   6  1               1           1             1              0       1
//-4 -5  0               1           0             0              0       0
//-5 -4  1               1           1             1              0       1/*
此題分兩種情況,一種是x,y異號,當x為正y為負的時候肯定返回0,當x為負y為正的時候肯定返回1,另外一種是當x,y同號的時候就是直接相減判斷,這樣做的目的是當防止他倆相加或相減正溢位或負溢位,
判斷x,y的大小如果x<y返回1否則返回0,x1,y1右移31位,當他們是正數的時候返回0,否則返回-1,而judge1是為了限制他的判斷條件當x,y同號的時候返回1否則返回0,
Judge2是為了判斷x,y異號的時候的返回值,first是判斷x-y返回的正負,但是我用y-x是因為y-x取非這樣的話-1變成0,0變成1,更方便計算,middle是把只取first中同號判斷部分二和judge2相或是判斷整體的


 * satAdd - adds two numbers but when positive overflow occurs, returns
 *          maximum possible value, and when negative overflow occurs,
 *          it returns minimum positive value.
 *   Examples: satAdd(0x40000000,0x40000000) = 0x7fffffff
 *             satAdd(0x80000000,0xffffffff) = 0x80000000
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 30
 *   Rating: 4
 */
正溢位=0111111111111;
負溢位=1000000000000;
int satAdd(int x, int y) {
Int ans=x+y;
Int middle=(((x^ans)&(y^ans))>>31;
Int ans1=((ans>>(middle&31)));
Int ans2=middle<<31;
  return ans1+ans2;
}
這是個判斷溢位的題,如果x+y沒有溢位就正常輸出x+y,否則就輸出0x7fffff
ans是算出x+y的值,如果x+y沒有溢位的話middle得出的值就是0,ans1得出的結果是ans右移0位,而ans2也是0對答案沒有影響,
但當x+y溢位的時候ans變成0x800000得到middle為-1而ans1會根據middle改變而右移31位,ans2會左移31位變成0x800000 再和ans1的-1相加得到0x7fffff
/* 
 * float_twice - 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
 *   Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
 *   Max ops: 30
 *   Rating: 4
 */
unsigned float_twice(unsigned uf) {
if((uf&0x7f800000)==0))
uf=(uf&0x80000000)|(uf&0x007ffff)<<1);
else
    if((uf&0x7f800000)!=0x7f800000)
uf+=0x00800000;
//else
if((uf&0x7800000)==0x7f800000)
    uf=uf;
  return uf;
}
//0x7800000      0 11111111 00000000
三種情況判斷
第一種就是階碼全為0,只有尾數的第一個是保證負數不變號 第二個是該數的尾數部分乘以2倍
第二種就是階碼不全為1,直接加上指數的1 就是乘以二倍了
第三種就是階碼全為1輸出原值
第一個if判斷是
/* 
 * float_abs - Return bit-level equivalent of absolute value of 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 representations of
 *   single-precision floating point values.
 *   When argument is NaN, return argument..
 *   Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
 *   Max ops: 10
 *   Rating: 2
 */
unsigned float_abs(unsigned uf) {
/**/
	unsigned ALL = 0x7FFFFFFF;	
	unsigned minNaN = 0x7F800001;
	unsigned temp = uf & ALL;
	if (temp >= minNaN) return uf ; 
						else return temp;
}
求浮點型數的絕對值,由題意知 當該無符號正數屬於NaN的時候返回原值 其他的情況下返回其絕對值,ALL是01111111,來保證uf的值變成正數,

題意是當uf大於0x7F8000001返回uf否則返回絕對值 而float二進位制碼中正負的判斷只有第一位決定第一位為0是正數 第一位為1位1負數,temp是返回的正數 無論uf是正是負

/* 
 * isEqual - return 1 if x == y, and 0 otherwise 
 *   Examples: isEqual(5,5) = 1, isEqual(4,5) = 0
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 5
 *   Rating: 2
 */
int isEqual(int x, int y) {
    !(a^b)
  return 2;
}
非常簡單,如果x,y相同就返回1否則返回0,一看就知道是異或的相反 相同為0不同為1,再取個非 直接得到結果

#include<stdio.h>
void printBin(int n){
if(n==0) return;
printBin(n/2);	//列印前k-1位
printf("%d",n%2);//列印最後一位

}