DataLab이란?
DataLab은 Carnegie Mellon University의 컴퓨터과학 학부에서 제공하는 프로그래밍 및 컴퓨터 아키텍처 교육 리소스입니다. DataLab은 학생들에게 컴퓨터 과학 및 컴퓨터 시스템의 기본 원칙을 가르치고 이해하는 데 도움을 주기 위해 고안되었습니다.
DataLab은 컴퓨터 과학 교육의 일환으로 사용되며, 컴퓨터 시스템 및 소프트웨어에 대한 깊은 이해를 개발하는 데 도움을 줍니다.
깔끔한 코드인지는 모르겠으나.. 참고만 부탁드립니다.
bitNor
int bitNor(int x, int y){
return ~x & ~y;
}
bitNor함수의 경우는 NOR연산자를 구현하는 것입니다. 여기서 조건은 '|' 연산을 제외하고 구현해야합니다.
여기서는 드모르간 법칙을 사용하여 ~(x | y) -> ~x & ~y로 만드는 것입니다.
allEvenBits
int allEvenBits(int x){
int mask = 0x55;
mask = (mask << 8) | mask;
mask = (mask << 16) | mask;
return !((x & mask) ^ mask);
}
allEvenBits함수는 모든 짝수 자리가 1인지 확인하여 모두 1이면 1을 반환하고, 아니면 0을 반환하는 함수이다.
여기서 0x55555555은 아래의 bit형태를 띄는데 홀수자리라고 착각하는 사람도 있지만 0123...이기 때문에 0번째 자리부터 짝수로 칩니다.
0x55555555 = 0101 0101 0101 0101 0101 0101 0101 0101
이를 bitmasking으로 이용해서 짝수자리의 값만을 얻어서 mask와의 일치여부로 값을 반환합니다.
float_abs
unsigned float_abs(unsigned uf){
if(uf > 0xFF800000) return uf;
return uf & 0x7FFFFFFF;
}
float_abs함수는 부동소수점을 알아야합니다.

floating point는 sign + exp + frac 으로 구성됩니다.
이 함수에서 기능은 NaN은 그대로 출력하고, 아닌경우는 절댓값으로 실수를 반환합니다.
따라서 NaN을 먼저 구분해야합니다.
NaN은 지수부 부분이 모두 1이고 frac부분이 적어도 하나 1인경우 NaN입니다.
따라서 uf가 0xFF800000보다 크다면 NaN인 것입니다. 그래서 이 경우에는 그대로 출력합니다.
그 외의 경우에는 부호비트를 0으로 바꾸어서 값을 반환하면 됩니다.
isGreater
int isGreater(int x, int y){
int signX = x>>31;
int signY = y>>31;
int equal = (!(signX ^ signY)) & ((~y+x) >> 31);
int nequal = signX & !signY;
return !(equal | nequal);
}
isGreater함수는 x가 y보다 크면 1 아니면 0을 반환하는 함수입니다.
여기서는 두 가지 경우로 나누어서 생각했습니다. x와 y의 부호가 같은 경우, x와 y의 부호가 다른 경우로 나눕니다.
먼저 x,y의 부호가 같은 경우에서는 x,y의 부호가 다른 경우를 배제하기 위해서 !(signX^signY)을 사용했습니다.
그리고 부호가 같은 경우 x-y의 부호비트가 0이면 x가 큰 것이고 1이면 y가 큰 것입니다. 따라서 x가 y보다 크려면 0을 반환해야 합니다.
그 다음으로 x, y의 부호가 다른 경우에서는 signX & !signY로 값을 구했는데, 부호가 다른 경우는 (+,-), (-,+)이기 때문에 x가 y보다 큰 경우만 0을 반환하고, 아니면 1을 반환하게 만든것 입니다.
그래서 부호가 같은경우와 부호가 다른경우가 모두 0을 반환했을 때만 x가 y보다 크다는 것임으로 1을 반환합니다.
addOK
int addOK(int x, int y){
int msb_x = x >> 31;
int msb_y = y >> 31;
int msb_xy = (x+y) >> 31;
return !((msb_x ^ msb_xy) & (msb_y ^ msb_xy));
}
addOK함수는 두 값을 더했을 때 overflow가 발생하면 0을 반환하고, overflow가 발생하지 않으면 1을 반환하는 함수이다.
overflow가 발생하는 경우는 양수 + 양수 = 음수, 음수 + 음수 = 양수인 두 경우가 있다. 따라서 부호비트를 이용해서 이를 해결했습니다.
x와 x+y의 부호가 다르면 1을 반환하고, y와 x+y의 부호가 다르면 1을 반환하여 둘다 1인 경우는 ! 연산자로 0을 반환하도록 하였습니다.
만약 x와 x+y가 부호가 같으면 0이고, y와 x+y가 부호가 같으면 0을 반환하여 0인 경우 ! 연산자로 1을 반환하도록 하였습니다.
bang
int bang(int x){
int result = x | (~x + 1);
return (result >> 31)+1;
}
bang함수는 !연산자를 !연산자를 사용하지 않고 구현하는 함수입니다. 즉, 0인 경우 1을 반환하고, 다른 정수인 경우 0을 반환하는 것입니다.
이를 구현하기 위해서는 x와 x의 보수를 or연산했을 때 0이 아닌 정수들의 경우는 signbit가 1이 나오고 0인 경우만 signbit가 0이 나온다. 그래서 위의 코드와 같은 방식으로 구현했습니다.
'CS 이론 > 시스템 프로그래밍' 카테고리의 다른 글
| malloc lab (1) | 2023.12.19 |
|---|---|
| bomblab (1) | 2023.10.17 |