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)
有些限制还是挺松的,有些过了就懒得再优化了。也没看别人的,不知道他们解法如何。