비트 연산과 비트 플래그

namu·2022년 7월 1일

#pragma region 비트 연산

언제 필요한가?
비트 단위의 조작이 필요할 때

  • 대표적으로 BitFlag

~ bitwise not
단일 숫자의 모든 비트를 대상으로 0은 1, 1은 0으로 바꿈

& bitwise and
두 숫자의 모든 비트 쌍을 대상으로 and를 한다.

| bitwise or
두 숫자의 모든 비트 쌍을 대상으로 or를 한다.

^ bitwise xor
두 숫자의 모든 비트 쌍을 대상으로 xor를 한다.

int a = 1;
int b = 123;
a = a ^ b;
a = a ^ b;

<< 비트 좌측 이동
비트열을 N만큼 왼쪽으로 이동
넘치는 N개의 비트는 버림. 새로 생성되는 N개의 비트는 0.
*2를 할 때 자주 보이는 패턴

'>>' 비트 우측 이동
비트열을 N만큼 오른쪽으로 이동
넘치는 N개의 비트는 버림.
왼쪽 생성되는 N개의 비트는

  • 부호 비트가 존재하는 경우 부호 비트를 따라감 (부호있는 정수라면 이 부분을 유의)
  • 아니면 0

실습
0b0000 [무적][변이][스턴][공중부양]

bool stunned;
bool polymorph;
...

unsigned char flag; // 부호를 없애야 >>를 하더라도 부호비트가 딸려오지 않음

// 무적 상태로 만든다
flag = (1 << 3); // 컴파일러가 8로 대체시켜 줌.
mov byte ptr [flag (015C151h)], 8

// 변이 상태를 추가한다 (무적 + 변이)
flag |= (1 << 2);
movzx eax, byte ptr [flag (015C151h)]
or eax, 4
mov byte ptr [flag (015C151h)], al

// 무적인지 확인 bitmask
bool invincible = (flag & (1 << 3)) != 0;
movzx eax, byte ptr [flag (015C151h)]
and eax, 8
je main+56h (0151FC6h)
mov dword ptr [ebp-0DCh], 1
jmp main+60h (1051FD0h)
00151FC6 mov dword ptr[ebp-0DCh], 0
mov cl, byte ptr [ebp-0DCh]
mov byte ptr [invincible], cl

// 무적이거나 스턴 상태인지 확인
bool studnOrInvincible = (flag & 0b1010) != 0;
// 마스크를 하드코딩하기 싫다면?
bool mask = (1 << 3) | (1 << 1);

#pragma endregion

profile
안녕하세요

0개의 댓글