CSAPP Data Lab

错误: fatal error: bits/libc-header-start.h: No such file or directory #include <bits/libc-header-start.h>

出现这个错误时,这多半是你所编译的项目是在64位机器上生成32位的项目,你需要安装对应的gcc 32位的库;此时检查gcc一定有-m32的存在;

你系统中gcc没有安装multilib 库;使用这个库可以在64位的机器上产生32位的程序或者库文件;

你可以选择:apt install gcc-multilib进行完善安装;

也可以只编译特定平台的文件: 例如 make x86_64; 具体编译的目标,请查看Makefile文件进行阅读;

无法在wsl子系统下正确运行csapp实验1datalab的实验程序

https://www.jianshu.com/p/69872ca47f9a

不过我本地要先装gcc-5

$ sudo apt install gcc-5 

Based on some tinkering I was doing with qemu for some ARM dev, I think I may have found a technique to allow general 32-bit support in WSL. Hat-tip to @therealkenc for the concept 😁

Edit: requires "Fall Creators Update", 1709, build 16299 or newer (I think)

Presuming a fresh Ubuntu WSL instance, you'll need to install the qemu-user-static package, add the i386 binfmt, enable the i386 architecture, update your package lists, and install some i386 packages:

Install qemu and binfmt

sudo apt update
sudo apt install qemu-user-static
sudo update-binfmts --install i386 /usr/bin/qemu-i386-static --magic '\x7fELF\x01\x01\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x03\x00\x01\x00\x00\x00' --mask '\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xf8\xff\xff\xff\xff\xff\xff\xff'

[Edit: whoops, need to update package lists, added sudo apt update]

This will activate i386 support by causing them to be executed through qemu-i386-static, and drop a config file into /var/lib/binfmts/ for future reactivation.

You will need to reactivate this every time you restart WSL and want i386 support:

sudo service binfmt-support start

Enable i386 architecture and packages

sudo dpkg --add-architecture i386
sudo apt update
sudo apt install gcc:i386

Try it out

$ file /usr/bin/gcc-5
/usr/bin/gcc-5: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=2637bb7cb85f8f12b40f03cd015d404930c3c790, stripped

$ /usr/bin/gcc-5 --version
gcc-5 (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ gcc helloworld.c -o helloworld

$ ./helloworld
Hello, world!

$ file helloworld
helloworld: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=3a0c7be5c6a8d45613e4ef2b7b3474df6224a5da, not stripped

Proof

And to prove it really was working, disable i386 support and try again:

$ sudo service binfmt-support stop
 * Disabling additional executable binary formats binfmt-support [ OK ]

$ ./helloworld
-bash: ./helloworld: cannot execute binary file: Exec format error

以下是我的解法(正文)

//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 - return minimum two's complement integer 
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 4
 *   Rating: 1
 */
int tmin(void) {
  return 1 << 31;
}
//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 !!~x & !(x + x + 2);
}
/* 
 * 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 = 85;
  y = (y << 8) | y;
  y = (y << 16) | y;
  return !((x | y) + 1);
}
/* 
 * negate - return -x 
 *   Example: negate(1) = -1.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 5
 *   Rating: 2
 */
int negate(int x) {
  return ~x + 1;
}
//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 y = x + (~48 + 1);
  int z = x + (~58 + 1);
  return !(y >> 31) & !((z >> 31) + 1);
}
/* 
 * 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) {
  x = !x + ~0;
  return (y & x) | (z & ~x);
}
/* 
 * 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 a = !(x >> 31), // a >= 0
      b = !(y >> 31), // b >= 0
      c = !!((x + ~y) >> 31); // x - y - 1 < 0   <=>  x - y <= 0
  return !(a & !b) & ((!a & b) | c);
}
//4
/* 
 * logicalNeg - implement the ! operator, using all of 
 *              the legal operators except !
 *   Examples: logicalNeg(3) = 0, logicalNeg(0) = 1
 *   Legal ops: ~ & ^ | + << >>
 *   Max ops: 12
 *   Rating: 4 
 */
int logicalNeg(int x) {
  x |= x >> 16;
  x |= x >> 8;
  x |= x >> 4;
  x |= x >> 2;
  x |= x >> 1;
  return ~x & 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) {
  // x = !x + ~0;
  // return (y & x) | (z & ~x);
  int r = 0, s = 0, xh = 0;
  x ^= x >> 31;
  xh = x >> 16;
  s = !xh + ~0;
  r = 16 & ~s;
  x = (xh & s) | (x & ~s);
  xh = x >> 8;
  s = !xh + ~0;
  r += 8 & ~s;
  x = (xh & s) | (x & ~s);
  r += !x; // 0
  x >>= 1;
  r += !x; // 1
  x >>= 1;
  r += !x; // 2
  x >>= 1;
  r += !x; // 3
  x >>= 1;
  r += !x; // 4
  x >>= 1;
  r += !x; // 5
  x >>= 1;
  r += !x; // 6
  x >>= 1;
  r += !x; // 7
  return 34 + ~r;
}
//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
 *   Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
 *   Max ops: 30
 *   Rating: 4
 */
unsigned floatScale2(unsigned uf) {
  unsigned s = uf & (1 << 31), e = (uf >> 23) & 255, f = uf << 9 >> 9;
  if (e == 255) return uf;
  if (e) {
      e += 1;
      if (e == 255) f = 0;
      return s | (e << 23) | f;
  }
  f <<= 1;
  if (f >= (1 << 23)) {
      e = 1;
      f ^= (1 << 23);
  }
  return s | (e << 23) | f;
}
/* 
 * 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) {
  unsigned s = uf & (1 << 31), e = (uf >> 23) & 255, f = uf << 9 >> 9;
  if (e == 255) return 0x80000000u;
  if (e <= 126) return 0;
  e -= 127;
  if (e >= 31) return 0x80000000u;
  f |= 1 << 23;
  if (e <= 23) return (s ? -1 : 1) * (f >> (23 - e));
  return (s ? -1 : 1) * (f << (e - 23));
}
/* 
 * 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) {
    if (x > 127) return 0x7F800000;
    if (x < -149) return 0;
    if (x <= -127) return 1 << (x + 149);
    return (x + 127) << 23;
}

写了几天,终于写完了,好棒棒。感觉就像做题答题...

Correctness Results     Perf Results
Points  Rating  Errors  Points  Ops     Puzzle
1       1       0       2       8       bitXor
1       1       0       2       1       tmin
1       1       0       2       7       isTmax
2       2       0       2       7       allOddBits
2       2       0       2       2       negate
3       3       0       2       12      isAsciiDigit
3       3       0       2       7       conditional
3       3       0       2       16      isLessOrEqual
4       4       0       2       12      logicalNeg
4       4       0       2       48      howManyBits
4       4       0       2       20      floatScale2
4       4       0       2       21      floatFloat2Int
4       4       0       2       9       floatPower2

Score = 62/62 [36/36 Corr + 26/26 Perf] (170 total operators)

有些限制还是挺松的,有些过了就懒得再优化了。也没看别人的,不知道他们解法如何。

posted @ 2020-11-24 23:23  tkandi  阅读(442)  评论(0编辑  收藏  举报