본문 바로가기

Research/Reverse

About overflow flag




오버플로우 플래그에 관하여

2011년 8월 22일 작성본



의문의 시작은 아래 밑줄 친 부분 때문인데,


양수 + 양수 = 음수 , 음수 + 음수 = 양수 일때 OF 가 발생한다.

OF는 두개의 피연산자 부호가 다를 경우 절대 발생 하지 않는다.

 

모 사이트에 위와 같이 나와 있었다.


원래 알고 있던 바, OF는 부호 있는 인자에 대한 오버플로우 판단 플래그이며
피연산자 부호와는 상관이 없다고 알고 있었다.

아래는 책을 참조하여 만든 플래그표.

왼쪽 피연산자 

오른쪽 피연산자 

연산자들의 관계 

플래그에 미치는 영향 

설명 

X<0

Y>0X<YOF=1 SF=0 ZF=0

X가 음수이고 Y가 양수이며

오버플로우가 발생한 경우로,

결과값은 양수다.

X>0Y<0X>YOF=1 SF=1 ZF=1

위의 경우와 반대의 경우로,

오버플로우가 발생하며

결과값은 음수다. 




#include <stdio.h>

main()

{
short value1;

__asm

{
xor ax, ax
xor bx, bx

mov ax, 0x7fff // 32767

mov bx, 0xffff // -1

sub ax, bx // 00008000

mov value1, ax

}

printf("%d", value1);

}

32767 - (-1) 형태의 계산을 어셈블리 코드로 표현했다.
short 형의 limit 범위는 -32768 ~ 32767 이며, 정상적인 계산 결과라면 32768 이 되겠지만
결과 -32768이 되는 코드이다.

sub명령이 떨어지고 난 뒤에 OF가 1로 변하는 모습을 확인했다.






산술 및 논리 연산에서 중요하게 취급되는 플래그 중 하나가 오버플로우 플래그이며,

이름에서 나타나듯 CF, OF 두 가지가 있기 때문에

오버플로우 플래그 전체를 OF라고 줄여서 표현하긴 어렵다.


이름에서 알 수 있다시피 이들은 산술 연산값이

변수값의 정상적 범위를 초과했을 때에 설정되는 플래그이다.

CF, OF의 차이점은 프로그램 내의 데이터 타입과 관련이 있다.


오버플로우가 발생했는지에 대한 판단을 위해서는

이 값이 부호가 있는지 없는지가 항상 고려되어야 하며,

CF와 OF가 설정되는 조건은 부호 유무에 따라 달라진다.


예를 들어,


mov ax, 0x1126 (10진수 4390)

mov bx, 0x7200 (10진수 29184)

add ax, bx


이 값의 결과는 0x8326, 10진수로 33574.


short 형(ax, bx)의 최대범위는 위에서 확인했듯 -32768 ~ 32767 이기 때문에,

정상범위를 초과해버린 ax의 값은 -31962가 되어 오버플로우가 발생한다.

반면, unsigned short 의 경우 0~65535 의 범위를 가지므로

오버플로우가 일어나지 않는다.


부호없는 값으로 봤을 때에는 별 문제가 없으나

부호있는 값으로 봤을 때에는 오버플로우가 발생하게 되고,

OF(부호있는 인자에 대한 오버플로우)는 1로

CF(부호없는 인자에 대한 오버플로우)는 0으로 셋팅이 된다.