|
C/C++ 고수분들에겐 뭐 이런 다 아는 얘기하냐라고 반문하실 수 있겠지만 생각보다 저 두 연산자들의 집합의 차이를 조금씩 헷갈려하는 분들이 있는 것 같아서 정리 차원에서 쓴다. &&, ||, !는 이른바 Logical operator로 Boolean으로 결과가 나온다. 참 아니면 거짓, 이 두 가지 밖에 없다. 반면, &, |, ~는 그냥 일반 +, - 처럼 산술연산이다. 특히 ~는 0과 1을 뒤집는 1's complement를 구해주는 연산으로 !과 결코 혼동해서는 안된다. 또 (a && b) 에서 expression a가 0이면 b는 아예 실행도 되지 않고 바로 전체 값을 false로 반환한다는 것도 잘 알 것이다. || 역시 비슷하게 작동한다. C++ 표준 (5.15) 에는 이것을 명확하게 보장하고 있다.
심심한 관계로 실제 C/C++ 컴파일러가 위 6가지 연산을 어떻게 만들어내는지 살펴보았다. i = j & k; 별 내용없다. 이들 연산자는 덧셈과 같은 산술 연산자이므로 그야말로 거기에 대응되는 인스트럭션으로 대치되었음을 알 수 있다. 따라서 if (a & b)가 있을 때, a가 아무리 0을 반환한다해도 그냥 끝나는 것이 아니라 b도 반드시 값을 구하게 된다. 그렇다면 Boolean 연산자들의 결과는? 위와 같이 대응되는 연산자가 없다. &&와 ||는 0과 같은지를 비교하는 분기문들로 이루어져있다. ! 역시 이에 해당하는 연산자가 있을 것 같다는 기대와 달리 다르게 표현되고 있다. 옆에다 주석으로 어떤 의미인지 적어봤다. i = j && k; 이걸 이해하려면 x86 Flags register에 대한 지식이 좀 필요하다. x86은 어떤 연산을 수행하고 나면 결과값 외의 여러 상태 변화를 Flags register에 담는다. 예를 들어, parity 값을 저장한다거나, 연산 결과가 표현 범위를 벗어났음을 뜻 하는 overflow 여부를 레지스터에 담는다. 비슷하게 ZF라는 Zero flag는 이전 연산의 결과가 0인지를 기억한다. ZF = 1이라면 이전 연산 결과가 0이라는 이야기다. x86 TEST 명령어는 두 피연산자를 & 연산하고 결과 값은 버리고 각종 플래그들을 채워준다. je는 "Jump if equal" 이라는 뜻이다. 구현은 ZF == 1일 때 주어진 주소로 점프하도록 되어있다. 왜 같을 때 점프하라는데 ZF 플래그 값을 보는지 궁금해할 것이다. 보통 if 문은 CMP과 같은 두 피연산자를 비교하는 명령어와 je, jne와 같은 조건분기명령어 세트로 이루어진다. 여기서 x86 CMP 연산은 두 인자를 빼는 SUB와 같은 역할을 한다. 그러나 TEST처럼 결과 값은 버리고 플래그 상태만 바꾼다. 따라서 두 피연산자가 같다면 그것들의 뺄셈은 0이 될 것이고 ZF는 1이 된다. 따라서 je는 "같을 때 점프하라"는 뜻이 성립된다. jne는 "Jump if not equal". 이 지식만 있으면 저 x86 코드는 이해할 수 있을 것이다. !, Logical Not 연산 역시 비슷하고 dl은 edx 32비트 레지스터 중 하위 8비트 부분만 가리킨다. Boolean이 1바이트라는 정의를 나름대로 충실히 따르고 있는 셈.
p.s. 008D11CD 주소에 있는 "xor edx, edx"는 edx에 0을 대입하는 코드이다. 자기 자신을 xor 하면 당연히 0이 나오기 때문에 저렇게 쓴 것인데 왜 명시적으로 "mov edx, 0"을 쓰지 않고 저렇게 표현했을까? x86 코드를 보면 0으로 세팅하는 것을 "xor, eax eax"와 같은 코드로 주로 대체한다. 왜 이렇게 했냐면 x86에서 골치아프게 존재하는 (다른 명령어셋도 비슷할 듯) partial register stall을 막기 위해서다. 펜티엄 프로부터 CPU가 xor eax, eax 같은 형태가 오면 특별하게 처리해서 의존성이 안 걸리게 해서 시간 낭비를 막아주도록 하고 있다.
최근 등록된 덧글
zzzzzzzzzzzzzzzzz..
by xxx at 23:10 저도 논문을 위해 작문위주의.. by Gerald at 10/11 opaque type은 내부를 알 .. by 몽몽이 at 10/09 샘이님 말씀에 한 표~ ^^;; by 엽우 at 10/09 Globefish 라는 Firefox .. by nurigis at 10/09 커스텀 사전에서 명사로 등.. by 게드 at 10/09 그렇네요. 제가 가지고 있는.. by object at 10/09 전산용어가 되면 뭐든지 셀 .. by 샘이 at 10/09 최근 등록된 트랙백
|