4. 시프트 Shift
쉬프트 연산의 동작은 대상이 되는 값을 왼쪽 또는 오른쪽으로 지정된 횟수만큼 이동시키는 연산이다.
1. 왼쪽 쉬프트
왼쪽 쉬프트는 지정된 횟수만큼 왼쪽으로 모든 비트를 이동하고, 오른쪽 두 비트는 0으로 채운다. 왼쪽 쉬프트는 부호와 상관없이 빈칸은 0으로 채워진다.
2. 오른쪽 쉬프트
오른쪽 쉬프트는 지정된 횟수만큼 오른쪽으로 모든 비트를 이동하고, 왼쪽 비트는 0 또는 1로 채워진다. 쉬프트의 대상이 되는 값이 부호가 없는 데이터이면 0으로 채워지고, 부호가 있는 데이터이면 부호 비트로 채워진다.
비트 연산 예제
unsigned char a=0xf0; //11110000(2)
한 비트 클리어(예> 5번 비트) a &= ~(0x1<<5);
연속된 여러 비트 클리어(예> 5,4,3번 비트) a &= ~(0x7<<3);
떨어져 있는 여러 비트 클리어(예> 5,3,2번 비트) a &=~((0x1<<5)+(0x3<<2));
한 비트 설정(예> 5번 비트) a |= (0x1<<5);
연속된 여러 비트 설정(예> 5,4,3번 비트) a |= (0x7<<3);
떨어져 있는 여러 비트 설정(예> 5,3,2번 비트) a |= (0x1<<5)+(0x3<<2);
한 비트 반전(예> 5번 비트) a ^= (0x1<<5);
연속된 여러 비트 반전(예> 5,4,3번 비트) a ^= (0x7<<3);
떨어져 있는 여러 비트 반전(예> 5,3,2번 비트) a ^= (0x1<<5)+(0x3<<2);
비트 검사(예> 5번 비트) a & (0x1<<5);
비트 추출(예> 6,5,4번 비트) b = (a>>4) & 0x7;
매크로 활용
1. 매크로 함수
매크로 함수는 전 처리기에 의해 함수 코드가 치환되는 형태로 작동된다.
분기 없이 실행되므로 분기에 의한 성능의 손실을 막을 수 있다. 비교적 짧은 코드는 매크로 함수를 사용하는 것이 좋다. 코드가 길 경우, 메모리 낭비가 심하다.
#define SQR(X) ((X)*(X))
인수를 제곱 하는 매크로 함수이다. SQR(X)를 호출하면 함수는 분기 하지 않고, 그 위치에 ((X)*(X))코드가 치환된다.
2. 비트 연산의 매크로 적용
비트 연산은 임베디드 소프트웨어 개발에서 자주 발생하므로 매크로로 정의해서 활용하면 매우 편리하다.
매크로의 인자는 data, area, loc이다. data는 비트조작을 할 대상으로 값이나, 변수를 대입해주고, area는 연속된 비트조작에서 연속 비트를 나타낸다. 예를 들어 111(2)처럼 연속 3비트라고 하면 0x7을, 연속 2비트이면 11(2)이므로 0x3을 대입한다. 마지막 loc은 조작할 비트 위치를 대입한다.
//한 비트 클리어
#define ClearBit(data, loc) ((data) &= ~(0x1<<(loc)))
//연속된 여러 비트 클리어
#define ClearBits(data, area, loc) ((data) &= ~((area)<<(loc)))
//한 비트 설정
#define SetBit(data, loc) ((data) |= (0x1<<(loc)))
//연속된 여러 비트 설정
#define SetBits(data, area, loc) ((data) |= ((area)<<(loc)))
//한 비트 반전
#define InvertBit(data, loc) ((data) ^= (0x1<<(loc)))
//연속된 여러 비트 반전
#define InvertBits(data, area, loc) ((data) ^= ((area)<<(loc)))
//비트 검사
#define CheckBit(data, loc) ((data) & (0x1<<(loc)))
//비트 추출
#define ExtractBits(data, area, loc) (((data)>>(loc)) & (area))
void main(void) {
unsigned char a=0xf0;
unsigned char b; ClearBit(a, 5); //5번 비트 클리어
ClearBits(a, 0x7, 3); //5,4,3번의 연속3비트 클리어
SetBit(a, 5); //5번 비트 설정
SetBits(a, 0x7, 3); //5,4,3번의 연속3비트 설정
InvertBit(a, 5); //5번 비트 반전
InvertBits(a, 0x7, 3); //5,4,3번 연속3비트 반전
if(CheckBit(a, 5)) //5번 비트가 어떤 값인지 체크
printf("true"); //1이면 1을 반환 0이면 0을 반환
else //1이면 true를 0이면 false를 출력
printf("false");
b=ExtractBits(a, 0x7, 4); //6,5,4번 비트를 추출하여 b에 대입
}
'Embedded Linux' 카테고리의 다른 글
4. 비트 연산 -1 (0) | 2015.12.22 |
---|---|
3. C 프로그램에서 하드웨어 접근 방법 (2) | 2015.12.22 |
2. 임베디드 시스템 개발 환경의 특징 (0) | 2015.12.22 |
리눅스 디바이스 드라이버 프로그래밍 (0) | 2015.12.21 |
리눅스 커널 모듈 프로그래밍 (0) | 2015.12.21 |