본문 바로가기

My Study/Reversing

OF, CF, SF를 알아보자

아... 아침부터 대전을 갔다왔더니... 피로가..ㅠㅠ.. 
===============================================
어셈블리를 분석하면서 대부분 어셈블리 창, 레지스터창, 스택, 덤프창.. 이런것들만 많이 보게되는데.. 
플래그들을 무시할 순 없습니다. 더욱 확실한 분석을 위해선 플래그들 값을 잘 봐야만 하죠.
특히, 어셈블리를 C언어로 바꿀 때 해당 변수가 unsigned인지 .. signed인지를 제대로 알기위해선 플래그 값을 봐야겠죠.

그래서 OF, CF, SF 세개의 플래그를 알아보도록 하겠습니다. 아마 ZF같은건 다들 아실태니...

간단히 C코드를 짜봤습니다. 예제 코드를 보면서 설명을 쭉 하겠습니다. 길게 써봤자 지루하지요.. ^^;

z,a,b,c가 있고 각각의 값을 아래선 1씩 증가시켜주고있습니다.
int 같은 경우는 2147483647까지 값이 들어갈 수 있습니다. 1이 더해지면 마이너스(-)가 나와버리죠.
unsigned int 같은 경우는 4294967295까지 값이 들어갈 수 있습니다. 마찬가지로 1이 더해지면 마이너스가 나옵니다.

위 코드를 OllyDbg에서 보면서 플래그를 확인해 보았습니다.

OF, CF, SF 세개의 플래그만 보도록 하겠습니다.
z에 1 더했을 때
OF = 0
CF = 0
SF = 0

a에 1 더했을 때
OF = 1
CF = 0
SF = 1

b에 1 더했을 때
OF = 1
CF = 0
SF = 1

c에 1 더했을 때
OF = 0
CF = 1
SF = 0

일단 결과는 이렇게 되는데 제가 예상했던 결과하고 달라버리니... 당황스럽군요.
사실 unsigned int로 선언된 변수에 2147483647를 넣고 1을 더했을 때 오버플로우 난게 없으므로 플래그에는 아무런 변화가 없을 줄 알았습니다. 하지만 제 예상이 빗나겠군요. 일단은 우기지 말고 눈에 보이는 결과를 보면서 이야기를 해보겠습니다.

위 결과에서 SF의 역할은 확실해졌습니다. 
바로 최상위 32번째 비트의 값을 나타냅니다. 32번째 비트값이 0이면 0, 1이면 1입니다.

위 결과를 보고 OF의 정의를 내려보겠습니다.
0x7FFFFFFF이하의 값이 연산 후 0x80000000 이상으로 값이 넘어가게되면 OF는 1로 됩니다.
signed, unsigned 상관없이 말이죠.

이번엔 CF의 정의입니다.
0xFFFFFFFF이하의 값이 연산 후 0xFFFFFFFF을 넘어가게되면 최상위 비트는 짤리게되고 CF의 값은 1로 설정됩니다.

이렇게 정의해놓으니 signed와 unsigned의 차이점을 해깔리게되는군요. 
플래그 값만 봐서는 signed나 unsigned나 같기때문이죠.

이것참.. ^^; 그리고 printf로 a,b값을 출력해보게되면 둘다 값이 같습니다. 
아마 printf에서는 서식문자를 지정해주어야하니까 그럴것입니다.

그래서 cout을 사용해 출력을 해보았습니다.

cout에서는 signed와 unsigned를 감지하고 각각 자료형에 맞게 출력을 해주는군요.

그러면 cout은 뭘 보고 unsigned 인지 signed인지 감지를 하는지 궁금하군요. 
signed나 unsigned나 1을 더했을 때 셋팅되는 플래그 값은 같은데 말이죠..

일단 각 플래그의 결론은 내려보았고.. 남은 과제는 cout의 출력 방법이군요. ( 기능이 너무 다양한 cout.. )
저도 공부를 해보겠지만.. 아시는분이 이 글을 보신다면.. 저에게 가르침을.. ^^;

정신이 없어서 너무 막 쓴거같군요.. ^^ 오늘은 쫌 쉬어야겠어요.. 흐엉..ㅠㅠ