[KNK] CH20 - Low Level Programming
CH20 Low Level Programming
비트 연산
Shift 연산
<<
,>>
,<<=
,>>=
- 정수 연산
- Portability 팁: unsigned 정수에만 사용하는 것이 좋다.
논리 연산
~
,&
,&=
, ,|
,|=
,^
,^=
- 일반 기요 연산자보다 비트 논리 연산자의 우선순위가 더 아래
비트 연산자로 비트 access
i |= 1 << j; /* sets bit j */
i &= ~( 1 << j ); /* clears bit j */
if( i & 1<<j); /* test bit j */
비트 연산자로 비트 필드(연속된 비트) 접근하기
/* 비트 필드 수정 */
i = i & ~ 0x0070 | 0x0050; /* stores 101 in bits 4-6*/
i = i & 0x0070 | j << 4; /*stores j in bits 4-6 */
/* 비트 조회하기(retrieving) */
j = i & 0x0007; /* retrieves bit 0-2 */
j = ( i >> 4 ) & 0x0007 /* retrieves bits 4-6 */
구조체로 비트 필드 다루기
선언
struct file_date{
unsigned int day: 5, // 0-4 bit
unsigned int month: 4, // 5-8 bit
unsigned int year: 5 // 9-15 bit
};
// just int type can be signed or unsigned depending on compiler
assignment
struct file_date fd;
fd.day = 28;
fd.month = 12;
fd.year = 8;
제약 사항
&
연산자를 사용할 수 없다. 예를 들어 scanf(“%d”&fd.day);
는 사용 불가능 하다. 일반적인 정수형 타입의 변수에 저장을 한 후 구조체 멤버 변수로 assign할 수는 있다.
이름 생략 또는 Padding
struct file_time{
unsigned int : 5; /* not used, padding */
unsigned int minutes : 6;
unsigned int hours: 5;
};
struct s{
unsigned int a: 4;
unsigned int: 0;
unsigned int b: 8;
};
위 예시에서
- 만약 저장 단위가 8비트라면 컴파일러는 첫 8비트에 a만 넣고 4비트를 스킵한 후 다음 8비트에 b를 넣을 것이다.
- 만약 저장 단위가 16비트라면 컴파일러는 첫 8비트에 a만 넣고 12비트를 스킵한 후 다음 8비트에 b를 넣을 것이다.
다른 low-level 테크닉들
머신 종속적인 타입 정의
typedef unsigned char BYTE;
typedef unsigned short WORD;
Union 사용하기
union int_date{
unsigned short i;
struct file_date fd;
};
void print_date(unsigned short n)
{
union int_date u;
u.i=n;
printf(“%d/%d/%d”,u.fd.month,u.fd.day,u.fd.year+1980);
}
Using Pointers as Addresses
BYTE *p;
p = (BYTE *) 0x1000;
The volatile
Type Qualifier
- it allows us to inform the compiler if any of the data used in a program is volatile
volatile
typically apperars in the declaration of a pointer variable that will point to a volatile memory locationvolatile BYTE *p; //*p will point to a volatile byte
댓글남기기