construcción del entorno de laboratorio csapp y lab1wp

1. Construcción del entorno

**

En primer lugar, necesitamos crear una máquina virtual de ubantu. Específicamente, Baidu
hará un buen trabajo en la máquina virtual y comenzará a construir el entorno. Haga clic derecho para abrir la terminal y luego ingrese el siguiente comando

apt-get update    //更新apt软件源
apt-get install sudo   //安装sudo
sudo apt-get install build-essential  //安装c/c++编译环境
sudo apt-get install gcc-multilib  //补充gcc的完整环境(gcc-multilib)
sudo apt-get install gdb  //安装gdb
sudo apt-get install make  //安装make

Cómo hacer las preguntas y cómo marcar bien o mal, ingrese las siguientes instrucciones (tome la primera pregunta bitXor como ejemplo)

make btest
./btest -f bitXor
./btest -g //总览所有题的得分

inserte la descripción de la imagen aquí
Una puntuación completa significa que lo hiciste bien
**

Dos.lab1wp

reglas int (traducidas por Baidu, debería poder entender)

Constantes enteras de 0 a 255 (0xFF), inclusive.
No se permiten constantes grandes como 0xffffffff.
Queda expresamente prohibido:

1. Use cualquier construcción de control como if, do, while, for, switch, etc.

2. Defina o utilice macros.

3. Defina cualquier función adicional en este archivo.

4. Llame a cualquier función.

5. Use cualquier otra operación como &&, | |, - o, ? :

6. Use cualquier forma de yeso.

7. Use cualquier tipo de datos que no sea int. Esto significa que
no se pueden utilizar matrices, estructuras o uniones.

1. joyas

//1
/* 
 * bitXor - x^y using only ~ and & 
 *   Example: bitXor(4, 5) = 1
 *   Legal ops: ~ &
 *   Max ops: 14
 *   Rating: 1
 */

El significado de la pregunta es usar ~, & para lograr XOR
~: para cada bit de binario, cambie 1 a 0 y cambie 0 a 1

Para x, y, solo puede haber dos combinaciones &, x&y y ~x & ~y, si es ~x&y, o ~y&x, no funcionará, puede negar ambas o usar 4 aquí, 5 para probar, 4&
5 =0100, ~4 & ~5=1010
Esto es para continuar tratando de combinar, para llegar a la respuesta

int bitXor(int x, int y) {
    
    
    return ~(x & y)&~(~x&~y);
}

2. tmin

/* 
 * tmin - return minimum two's complement integer 
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 4
 *   Rating: 1
 */

El significado de la pregunta es encontrar el valor mínimo del código de complemento a dos, 0x10000000 es el valor mínimo, pero solo puede ingresar entre 0 y 255 (0xFF), por lo que debe usar el desplazamiento a la izquierda <<, de la siguiente manera:

int tmin(void) {
    
    
    return 1 << 31;
}

3. isTmax

//2
/*
 * isTmax - returns 1 if x is the maximum, two's complement number,
 *     and 0 otherwise 
 *   Legal ops: ! ~ & ^ | +
 *   Max ops: 10
 *   Rating: 1
 */

El significado de la pregunta es que si la x aceptada es el valor máximo en binario, devuelve 1, de lo contrario es 0. El
valor máximo en binario es 0x7FFF FFFF. Asumiendo que es x, entonces x+1 es 0x8000 0000. En esta vez, XOR los dos para obtener 0xFFFF FFFF, más un '~', obtienes 0 y luego usas la negación lógica al regresar. Sin embargo, 0xFFFF FFFF y su +1 XOR también son 0xFFFF FFFF. En este momento, cuente el +1 dos veces '!', que es 0. En combinación con la operación AND, la implementación específica es la siguiente
:

int isTmax(int x) {
    
    
    int r=x+1;
    r=~(x^r);
    return !(r^x) &!!(x+1);   
}

4. todos los bits impares

/* 
 * 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
 */

El significado de la pregunta es devolver 1 cuando todos los bits impares son 1.
Solo 0xAAAA AAAA y 0xFFFF FFFF satisfacen todos los dígitos impares de 1. En este momento, se usa XOR para juzgar. Primero,
suponga que x es 0xAAAA AAAA. Para hacer un valor XOR 0xAAAA AAAA con x, de modo que sea Después de 0, use lógica NO para cambiar a 1.
Si x es 0xFFFF FFFF, debe agregar una operación AND aquí para que primero cambie a 0xAAAA AAAA y luego XOR para obtener 0.
Ahora hay otro problema es cómo dar 0xAAAA AAAA a la variable Para asigne un valor, aquí necesitamos usar la combinación de desplazamiento lógico a la izquierda y XOR para obtener
el valor específico de la siguiente manera:

int allOddBits(int x) {
    
    
    int q1=0xaa;
    int q2=q1<<8;  //q2=aa00
    int q3=q2^q1;  //q3=aaaa
    int q4=q3<<16; //q4=aaaa0000
    int q=q3^q4;  // q=aaaaaaaa
    q1=q&x; 
    return !(q1^q);
}

5.negar

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

El significado de la pregunta es tomar el valor opuesto
. Esto aún debe usarse ~. Para cada bit, 0 se convierte en 1, 1 se convierte en 0.
Tome x = 0xFFFF FFFF, por ejemplo, ~x = 0, 0 + 1 = 1 , y
luego tome x=0x8000 Para 0001, ~x+1=0x7FFF FFFD +1=0x7FFF FFFF
es como sigue:

int negate(int x) {
    
    
  return ~x + 1;  
}

6. esDígitoAscii

/* 
 * 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
 */

El significado de la pregunta es que si 0x30 <= x <= 0x39, el retorno es 1,
es decir, si x-0x30>=0&&x-0x39<=0 se devuelve como 1,
aquí x-0x39>=0 debería ser cambiado a x-0x3a<0 para una buena representación, por supuesto, también puede ser 0x39-x>0
y luego combinado con la operación lógica not '!' y OR,
de la siguiente manera:

int isAsciiDigit(int x) {
    
    
      
      return !(((x+~0x30+1)>>31)|!((x+~0x3a+1)>>31));             
}

7. condicional

/* 
 * conditional - same as x ? y : z
 *   Example: conditional(2,4,5) = 4
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 16
 *   Rating: 3
 */

El significado de la pregunta es darse cuenta de x?y:z, es decir, si x es verdadero, entonces el valor es y, de lo contrario, z primero usa dos negaciones lógicas
para cambiar el valor distinto de cero a 1, y el valor a 0 sigue siendo 0.
Si x es verdadero, entonces se convierte en x=0xFFFF FFFF, lo que es beneficioso para la operación Y.
Si no es verdadero, use la inversión lógica para cambiar x=0 en 0xFFFF FFFF
de la siguiente manera:

int conditional(int x, int y, int z) {
    
    
   x=!!x; //先将x化为0或1
   int a=(x<<31)>>31;
   return (a & y)+(~a&z);
}

8.esMenorOIgual

/*

  • isLessOrEqual: si x <= y, devuelve 1, de lo contrario, devuelve 0
  • Ejemplo: esMenosOrEqual(4,5) = 1.
  • Operaciones legales: ! ~ & ^ | + << >>
  • Operaciones máximas: 24
  • Calificación: 3
    */
    Significado del título: Si x<=y devuelve 1, de lo contrario es 0.
    Primero use XOR y la negación lógica para juzgar si x e y son iguales, y si son iguales, es 1

Si no son iguales, entonces x es un número negativo, y cuando y es un número positivo, es decir, cuando el bit de signo de x es 1 y el bit de signo de y es 0, podemos intentar que vuelva a 1 Primero, permita que x e y se desplacen a la derecha en 31 al mismo tiempo
., En este momento, x es 0xFFFF FFFF, y es 0, use la negación lógica para hacer que x sea 0, luego use la operación OR para que tanto x como y regresen a 0, y finalmente
use una negación lógica para convertirlo en 1. De hecho, aunque el método considerado sólo considera que x es un número negativo e y es un número positivo, también es aplicable cuando y es un número negativo y x es un número positivo.

Luego considere que cuando los bits de signo de x e y son consistentes, primero use XOR para determinar si los bits de signo son consistentes, y luego simplemente use x+~y+1=xy para obtener el número 0xFFFF FFFF, y use dos negaciones lógicas para convertirlo en 1, y luego dar las dos operaciones AND

Cualquiera de las tres condiciones anteriores se puede satisfacer
de la siguiente manera:

int isLessOrEqual(int x, int y) {
    
    
    int equal= !(x^y);
     
    int xh=x>>31;
    int yh=y>>31;
    int wudi=!((!xh)|yh);

    int yf=~y+1;
    int same=!(xh^yh);
    int jian=!!((x+yf)>>31);
    return equal|wudi|(same&jian);	
}

9.negativo lógico

/* 
 * 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 
 */

Significado de la pregunta: Use los símbolos anteriores para realizar la negación lógica
para cambiar el número que no es 0 a 0, y cambiar 0 a 1. Piénselo, 0 y su número opuesto son ambos 0, y por el contrario, la suma de números que no son 0 su signo de número opuesto debe tener un 1
u operación para obtener -1, y finalmente sumar un 1 para satisfacer
lo específico de la siguiente manera:

int logicalNeg(int x) {
    
    
     int xfh=(~x+1)>>31;  
     int xh=x>>31; 
     return (xh | xfh)+1; 
}

10.cuantos bits

/* 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
 */

Intención del título: para determinar cuántos dígitos tiene el número de entrada,
primero que nada, necesitamos invertir el número negativo, y cualquiera que sea el número positivo, es principalmente por la conveniencia de juzgar el número de dígitos
. necesita usar el método de dicotomía, primero determine si hay 16 dígitos,
y si es así, luego juzgue si hay 24 bits, de lo contrario, juzgue si hay 8 bits, y luego juzgue así 8, 4, 2, 1, 0
No hablaremos de eso aquí, solo pon el código directamente

int howManyBits(int x) {
    
    
   int sign = x >> 31;
   x = (~sign & x) | (sign & ~x); //取反
   int b16 = !!(x >> 16) << 4;//判断是否有16位
   x >>= b16;

   int b8 = !!(x >> 8) << 3; 
   x >>= b8;

  int b4 = !!(x >> 4) << 2;
  x >>= b4;

  int b2 = !!(x >> 2) << 1; 
  x >>= b2;

  int b1 = !!(x >> 1);
  x >>= b1;

  int b0 = x;
  return b16 + b8 + b4 + b2 + b1 + b0 + 1;//+1是因为就如果像0这样的数,判定的时候是有1位的
}

regla flotante

Las reglas de codificación son menos estrictas. Puede utilizar bucles y

mando condicional. Puede utilizar tanto enteros como sin signo.

Se pueden utilizar enteros arbitrarios y constantes sin signo. Puedes usar cualquier aritmética,

Realiza una comparación OR lógica en datos enteros o sin signo.

Queda expresamente prohibido:

1. Defina o use cualquier macro.

2. Defina cualquier función adicional en este archivo.

3. Llame a cualquier función.

4. Use cualquier forma de yeso.

5. Use cualquier tipo de datos excepto int o sin firmar. significa tu

No se pueden utilizar matrices, estructuras o uniones.

6. Utilice cualquier tipo de datos, operación o constante de coma flotante.

floatScale2

/*

*floatScale2-返回表达式2*f的等效位级别

*浮点参数f。

*参数和结果都作为无符号int传递,但是它们将被解释为单精度浮点值。

*当参数为NaN时,返回参数

*合法运算:任何整数/无符号运算,包括| |,&&&。如果,虽然

*最多操作符:30

*评级:4

*/

inserte la descripción de la imagen aquí
Esta imagen es un poco borrosa, échenle un vistazo juntos.
El primer bit es el bit de signo, los 8 bits del medio son el exponente y los últimos 23 bits son la mantisa.
s es el bit de signo, M es la mantisa , y E es el
número de punto flotante exponente . Se divide en estas cuatro categorías. Los normalizados son los ocho dígitos del medio! = 0 &! = 255, y los últimos son arbitrarios. Los no normalizados son los ocho dígitos del medio son 0, y los últimos son cualquier
valor. Infinito significa que los ocho dígitos del medio son 0xFF, y los últimos 23 dígitos son 0. La diferencia entre NaN e infinito es que los últimos 23 bits no son 0

Intención del título: devolver el doble del número pasado.
El valor de retorno de infinito y NaN es su propia
normalización, así que simplemente deje su código de orden + 1. Si no está normalizado, deje que se desplace un bit a la izquierda (por ejemplo, binario 10 turnos a la izquierda es 100)

El código se implementa de la siguiente manera:

unsigned floatScale2(unsigned uf) {
    
    
      unsigned exp=(uf&0x7f800000)>>23;
      unsigned sign=uf>>31&0x1;
      unsigned frac=uf&0x7FFFFF;
      unsigned res;
  
    	if(exp==0xff){
    
    
     	return uf;
   	}
  	else if(exp==0){
    
    
   	 frac<<=1;//
   	 res=(sign<<31)|(exp<<23)|frac;
 	 }
 	 else{
    
    
   	 exp++;
   	 res=(sign<<31)|(exp<<23)|frac;
 	 }
  return res;
}

floatFloat2Int

/*

*float2int-返回表达式(int)f的位级等效值

*对于浮点参数f。

*参数作为无符号int传递,但它将被解释为单精度浮点值。

*任何超出范围的东西(包括NaN和infinity)都应该返回

*0x80000000u。

*合法运算:任何整数/无符号运算,包括||,&&. also if, while

*最多符号位:30

*评级:4

*/

El significado de la pregunta: convertir el tipo de punto flotante uf al tipo int
No más. . .
No entiendo qué está pasando con 23 y 31. . .
solo se movió el código

int e = ((uf & 0x7F800000) >> 23) - 0x7F;
    int f = ((uf & 0x007FFFFF) | 0x00800000);

    if (!(uf & 0x7FFFFFFF) || e < 0)
        return 0;
    if (e > 31)
        return 0x80000000;

    if (e > 23)
        f = f << (e - 23);
    else
        f = f >> (23 - e);

    if (!(uf >> 31))
        return f;
    else
        return ~f + 1;

FloatPower2

/*

*floatPower2-返回与表达式2.0^x等效的位级别

*(2.0升为x的幂)用于任何32位整数x。

*返回的无符号值应具有相同的位

*表示为单精度浮点数2.0^x。

*如果结果太小,无法表示为denorm,则返回0. 如果太大,返回+INF。

*合法运算:任何整数/无符号运算,包括| |,&&&。如果,虽然

*最多:30

*评级:4

*/

fw sigue siendo malo,
y el código de manejo es el siguiente:

if(x>127)//overflow
      return 0x7f800000;//+inf 符号位0 阶码全1 尾数全0
 
    //规格化的 [-126,127]
    if(x>=-126)
    {
    
    
      unsigned exp = x+127;//加上bias
      return exp<<23;//只需改变阶数
    }
 
    //非规格化的 [-149,-127]
    if(x>=-149)
      return 0x1<<(x+149);//只需改变尾数
 
    //x<-149 too small to be represented
    return 0;

Supongo que te gusta

Origin blog.csdn.net/m0_51295934/article/details/123409878
Recomendado
Clasificación