CSAPP LAB

CSAPP LAB

丑话说在前头 不做不知道 一做吓一跳 是真的什么都不知道捏~

当然了还是和书中建议一般:

Don't cheat, even the act of searching is checting.

yub刚开始想整tmux玩https://www.jikecloud.net/supports/docs/tmux-intro/ 发现字体颜色太暗了眼睛要麻了(懒得调)最后还是去了terminal

Data Lab

bitXor(x,y)

只使用两种位运算实现异或操作.
^(异或)相异为1不用为0
~ 非 也就是按位取反
& 逻辑与 补码同为1才为1 其余为0

有点好笑的是yub刚开始忘记负数这茬了,没过脑子很简单的,haha 玉玉了

/* 
 * 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;
}//正数范围满足

只要分别计算 不同为0和不同为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);
}

也可以简写成

(x & y) | (~x & y) 
tmin()

使用位运算获取对2补码的最小 int 值.

说实话这个英语底子还是得加强哈 扫一遍题目yub以为是return两个数中最小的那个(怎么看也是有逻辑错位u 两个数不应该是较小的吗…)

/* 
 * tmin - return minimum two's complement integer 
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 4
 *   Rating: 1
 */
int tmin(void){
  return 0x1<<31;
}

C语言中int是整型,4bytes32位,根据补码变形为负数即可.

isTmax(x)

通过位运算计算是否是补码最大值.

给出允许可以使用^且前面已经求出了tmin yub觉得这下好办

/*
 * 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) {
  !(~((x + 1) + x) | !(x + 1));
}

后看了其他笔者的解法,yub感觉思维又缜密了一些~

/*
 * 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 i = x+1;//Tmin,1000...
  x=x+i;//-1,1111...
  x=~x;//0,0000...
  i=!i;//exclude x=0xffff...
  x=x+i;//exclude x=0xffff...
  return !x;
}

思路

前提:必须知道补码最大值是多少.(针对 int 类型),最大值当然是符号位为 0,其余全是 1.
在此说一下个人理解,最终返回值为 0 或 1,要想判断给定数 x 是不是补码最大值(0x0111,1111,1111,1111),则需要将给定值 x 向全 0 值转换判断,因为非 0 布尔值就是 1,不管你是 1 还是 2。根据我标注的代码注释理解,如果 x 是最大值,将其转换为全 0 有很多方法,不过最终要排除转换过程中其他的数值,比如本例子中需要排除 0xffffffffffffffff 的情况:将 x 加 1 的值再和 x 相加,得到了全 1(函数第二行),然后取反得到全 0,因为补码 - 1 也有这个特点,所以要排除,假设 x 是 -1,则 +1 后为全 0,否则不为全 0,函数 4-5 行则是排除这种情况。

allOddBits(x)

判断所有奇数位是否都为 1,这里的奇数指的是位的阶级是 2 的几次幂。重在思考转换规律,如何转换为对应的布尔值。

“(位)掩码”o.0? yub觉得是知识盲区一样 https://blog.csdn.net/qq_20233867/article/details/73743351

https://blog.csdn.net/u013279723/article/details/107447260

image-20230808185918104

/* 
 * 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 odd = (0xAA << 24) + (0xAA << 16) + (0xAA << 8) + 0xAA;
  return !((x & odd) ^ odd);
}

通过python探索,yub认为可以先构造位掩码再利用^关系解决问题(使用移位运算符构造出奇数位全 1 的数 mask ,然后获取输入 x 值的奇数位,其他位清零(mask&x),然后与 mask 进行异或操作,若相同则最终结果为 0,然后返回其值的逻辑非).

negate(x)

不使用 - 操作符,求 -x 值.

yub认为此题非常基础.取反得补码+1即可.

/* 
 * negate - return -x 
 *   Example: negate(1) = -1.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 5
 *   Rating: 2
 */
int negate(int x) {
  return ~x+1;
}
isAsciiDigit(x)

计算输入值是否是数字 0-9 的 ASCII 值.yub有惯性思维,(x-0x30>=0)&&(x-0x39<=0)

yub想到说用位操作,但是运用的时候还是很懵逼…

/* 
 * 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 sign = 0x1<<31;
  int upperBound = ~(sign|0x39);
  int lowerBound = ~0x30;
  upperBound = sign&(upperBound+x)>>31;
  lowerBound = sign&(lowerBound+1+x)>>31;
  return !(upperBound|lowerBound);
}

conditional(x, y, z)

使用位级运算实现 C 语言中的 x?y:z 三目运算符。又是位级运算的一个使用技巧。

yub今天无意间看到boolean觉得好像有点东西.

/* 
 * conditional - same as x ? y : z 
 *   Example: conditional(2,4,5) = 4
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 16
 *   Rating: 3
 */
//如果!x=0,mask=000000000,y&~mask==y,z&mask==0
//如果x==0,mask=0xffffffff,y&~mask=y&0=0,z&mask=z
int conditional(int x, int y, int z) {
 int mask = ~!x;
 return (y & ~mask) | (z & mask);
}
BUPT CSAPP Lab4是指北京邮电大学计算机科学与技术课程《CSAPP-深入理解计算机系统》的实验四。该实验主要涉及操作系统相关的内容,旨在帮助学生加深对操作系统的理解和认识。 该实验的主要内容是通过编写一个简单的Unix shell来实现一个命令行解释器。这个shell可以读取来自用户输入的命令,并执行这些命令。在实现过程中,需要学生理解和掌握进程控制、文件描述符、信号处理、文件I/O等操作系统的核心概念和技术。 实验4主要由以下几个部分组成: 1. 实现命令行解释器的基本功能,包括读取用户输入的命令、解析命令的参数和选项、执行命令等。此外,还需要处理输入输出重定向、管道、后台运行等特殊操作。 2. 实现信号处理功能,包括捕获和处理常见的信号(如SIGINT、SIGCHLD等),以及重新设置信号处理程序等。 3. 实现文件I/O功能,包括文件打开、读写、关闭等操作。需要学生理解文件描述符的概念和用法,并能正确地管理文件描述符。 4. 实现进程控制功能,包括创建新的进程、加载可执行文件、执行命令、等待子进程退出等。学生需要理解进程的创建、终止、调度等基本概念和原理,以及在实践中正确地使用这些操作。 通过完成该实验,学生可以加深对操作系统内核的理解,掌握操作系统的基本功能和组成,提高对计算机系统的整体把握能力。此外,实验也有助于学生培养编程能力、问题解决能力和团队合作能力等重要的综合素养。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值