전체 : 4,150,784 명
어제 : 0 명
오늘 : 0 명

Carry VS Overflow Flag 개념 잡기.

마플 | 2012.06.02 11:45 | 조회 9211


안녕하세요.

이번 글은 Carry 와 OverFlow Flag 에 대한 개념을 잡아보려고 합니다. 사실 그 동안 많이 접해왔지만 뭐가 뭐다라고 딱히 뚜렷하게 알고 있지는 못했습니다. 이번 기회에 아주 확실히 Carry 는 모다? OverFlow는 모다? 의 개념을 잡아볼까 합니다.


이번 글에서 다루고자 하는 내용 : Carry Flag 와 Overflow Flag
이번 글에서 얻을 수 있는 내용 : Carry Flag 와 Overflow Flag 의 개념과 차이점
이번 글의 기반 : x86 Windows Visual studio 2010
=====================================================
The CARRY flag and OVERFLOW flag in binary arithmetic
=====================================================
- Ian! D. Allen - idallen@idallen.ca - www.idallen.com
http://teaching.idallen.com/dat2343/10f/notes/040_overflow.txt


본론에 들어가기에 앞서 =====-==================================

정수 연산에서 "carry" 플래그와 "overflow" 플래그를 혼동하지 말아라. 각 플래그는 혼자, 혹은 함께 발생할 수 있다. CPU의 ALU는 당신이 signed 혹은 unsigned 연산을 수행하는지 신경쓰지 않는다. ALU는 항상 두 플래그를 어떤 정수 연산을 하든 적절히 세팅한다. ALU는 singed/unsigned 에 대해선 모른다. ALU는 단지 이진연산을 수행하고 flag를 적절히 세팅한다. 연산 후에 어떤 플래그를 체크할지는 당신의 몫이다.

만약 프로그램이 워드 사이즈의 비트를 unsigned 숫자로 취급한다면, 연산의 결과가 틀렸는지를 carry flag가 on 되었는지 통해 확인해야한다. 오버플로우 플래그는 unsigned 연산에선 신경쓸 필요없다. ( 오버플로우 플래그는 오직 signed 숫자와 관련해 생긴다. )

만약 프로그램이 워드 사이즈의 비트를 2의 보수 signed 값으로 다룬다면, 연산의 결과가 틀렸는지를 overflow flag가 on 되었는지 통해 확인해야한다. signed, 2의 보수 연산에서 carry flag는 신경쓸 필요 없다. ( 캐리 플래그는 오직 unsigned 숫자와 관련해 생긴다. )

In unsigned arithmetic, watch the carry flag to detect errors.
In unsigned arithmetic, the overflow flag tells you nothing interesting.

In signed arithmetic, watch the overflow flag to detect errors.
In signed arithmetic, the carry flag tells you nothing interesting.


영어
-------

"오버플로우 되다." 라는 영어 동사와 "오버플로우 플래그" 와 혼동하지 마라. "오버플로우 되다"라는 동사는 어떤 연산의 결과가 유효한 비트 숫자와 적합하지 않을때를 나타낼때 쓰인다. 그건 정수 연산이나 부동소수점 연산이나 뭐든간에 쓰일 수 있다. "오버플로우 플래그"는 ALU 에 의해 표시되는 특별한 어떤 설명이고, 이는 영어 동사 "오버플로우 되다" 와는 같지 않다.

영어로는 이렇게 말할 수 있다.
" 바이너리/정수 연산 결과가 오버플로우 되어 결과로 가용한 비트 수를 넘었고, 이는 캐리 플래그를 on 시키게 된다."
중요한건 여기서 "오버플로우 되어" 라는 동사가 "오버플로우 플래그가 on되었다. " 라는 것과는 같지 않다는 것이다.
연산 결과는 오버플로우 플래그의 변동 없이 오버플로우 될 수 있다.(동사)

믿기 어려우시다구요? 믿으세요.
다음의 예문을 보시죠.


 /* * * * * * * * * * * * * * * * * * * * * * * * *
*    Te.st OverFlow & Carry Flag
*    code by maple ( http://kese111.tistory.com )
*/

int _tmain(int argc, _TCHAR* argv[])
{
    int int1 = 0xC0000000; // 11000000000000000000000000000000
    int int2 = 0x40000000; // 01000000000000000000000000000000
    bool over = false;
    bool carry = false;
    //overflow Teast
    int1 = int1 + int2;
    

OVERFLOWTEaST:
    __asm{
        jo OVER
    }
CARRYTEaST:
    __asm{
        jc CARRY        
    }

Finish:
    if( over )
        printf("This is Over Case %xn", int1 );
    if( carry )
        printf("This is Carry Case %xn", int1 );
    getchar();
    return 0;

OVER:
    over = true;
    goto CARRYTEaST;

CARRY:
    carry = true;
    goto Finish;

    return 0;
}




위의 소스코드를 실행시킨 결과는 "This is Carry Case 0" 입니다.
이 연산은 분명히 오버플로우 되어 int1 에는 0 이 들어있습니다. 하지만 "오버플로우" 되었다고 "오버플로우 플래그" 가 on이 되지는 않습니다. 앞에 말씀드린 내용을 증명이나 하듯이 말이죠. 원리를 생각해보면 간단합니다. -_-;
int1 = -1073741824
int2 = 1073741824
보수를 취해서 덧셈을 하기 때문에 오버플로우가 되더라도 오버플로우 플래그를 on시키지 않는 것 입니다.


Carry Flag
----------

캐리 플래그가 on 되는 경우는 2가지가 있습니다.

1. 두 수의 합으로 발생한 carry 가 부호 비트(최고왼편)보다 앞에 더해질때

1111 + 0001 = 0000 (carry flag is turned on)

2. 두 수의 차로 발생한 carry(혹은 borrow란 용어를 쓰네요;)로 인해 부호 비트(최고왼편) 앞 비트로부터의 borrow가 발생해야 할때

0000 - 0001 = 1111 (carry flag is turned on)

다른 경우, 캐리 플래그는 off 됨
* 0111 + 0001 = 1000 ( carry flag is turned off [zero] )
* 1000 - 0001 = 0111 ( carry flag is turned off [zero] )

unsigned 연산에서, 캐리 플래그로 에러를 확인할 수 있다.
signed 연산에서, 캐리 플래그는 관심대상이 아니다.


Overflow Flag
-------------

오버플로우 플래그가 on 되는 바이너리/정수 연산도 두개다 :

1. 두 수의 합으로 부호 비트가 on 되었을때, "오버플러우" 플래그가 on된다.

0100 + 0100 = 1000 (overflow flag is turned on)

2. 두 수의 합으로 부호 비트가 off 되었을때, "오버플로우" 플래그가 on 된다.

1000 + 1000 = 0000 (overflow flag is turned on)

다른 경우, 오버플로우 플래그는 off 됨.
* 0100 + 0001 = 0101 (overflow flag is turned off)
* 0110 + 1001 = 1111 (overflow flag is turned off)
* 1000 + 0001 = 1001 (overflow flag is turned off)
* 1100 + 1100 = 1000 (overflow flag is turned off)

오직 세 숫자들의 부호 비트(최고왼편)를 보면 오버플로우 플래그가 on 이나 off 되는지 알 수 있다.

만약 2의 보수(signed) 연산을 수행한다면, 오버플로우 플래그는 이것이 잘못 됐는지를 나타낸다. - 두 양수를 더해서 음수를 얻거나 두 음수를 더해서 양수를 얻거나 하는 경우가 이를 나타낸다.

만약 unsinged 연산을 수행한다면, 오버플로우 플래그는 아무것도 의미하지 않으니 무시하면 되겠다.

이 규칙은 2의 보수 결과의 부호를 검사함으로서 에러를 검출하기 위함이다. 음수와 양수 간의 덧셈은 절대로 잘못될 수 없다. 왜냐면 두 수의 합이기 때문이다. 두 피연산자들이 각자의 숫자에 허용되는 값에 맞다면, 그 둘의 합의 결과도 적합하게 된다. 다른 부호간의 덧셈은 절대로 오버플로우의 플래그를 on 하지 않는다.

signed 연산에서, 오버플로우 플래그를 통해 에러를 탐지할 수 있다.
unsigned 연산에서, 오버플로우 플래그는 흥미로운게 없다.



ALU 이 오버플로우 플래그를 결정하는 방법
----------------------------------------
이 부분부터는 굳이 읽지 않으셔도 됩니다. 하지만 앞서 말한 내용이 쉬이 이해가 되지 않으신다면, 특히 제가 작성한 예제에서 캐리 플래그만이 on되는게 이해되지 않으신다면 이하 장을 읽어보시길 추천합니다.

번역은 더 안하겠습니다. ^^/


There are several automated ways of detecting overflow errors in two's
complement binary arithmetic (for those of you who don't like the manual
inspection method). Here are two:

Calculating Overflow Flag: Method 1
-----------------------------------

Overflow can only happen when adding two numbers of the same sign and
getting a different sign. So, to detect overflow we don't care about
any bits except the sign bits. Ignore the other bits.

With two operands and one result, we have three sign bits (each 1 or
0) to consider, so we have exactly 2**3=8 possible combinations of the
three bits. Only two of those 8 possible cases are considered overflow.
Below are just the sign bits of the two addition operands and result:

ADDITION SIGN BITS
num1sign num2sign sumsign
---------------------------

0 0 0
*OVER* 0 0 1 (adding two positives should be positive)
0 1 0
0 1 1
1 0 0
1 0 1
*OVER* 1 1 0 (adding two negatives should be negative)
1 1 1

We can repeat the same table for subtraction. Note that subtracting
a positive number is the same as adding a negative, so the conditions that
trigger the overflow flag are:

SUBTRACTION SIGN BITS

num1sign num2sign sumsign
---------------------------
0 0 0
0 0 1
0 1 0
*OVER* 0 1 1 (subtracting a negative is the same as adding a positive)
*OVER* 1 0 0 (subtracting a positive is the same as adding a negative)
1 0 1
1 1 0
1 1 1

A computer might contain a small logic gate array that sets the overflow
flag to "1" iff any one of the above four OV conditions is met.

A human need only remember that, when doing signed math, adding
two numbers of the same sign must produce a result of the same sign,
otherwise overflow happened.

Calculating Overflow Flag: Method 2
-----------------------------------

When adding two binary values, consider the binary carry coming into
the leftmost place (into the sign bit) and the binary carry going out
of that leftmost place. (Carry going out of the leftmost [sign] bit
becomes the CARRY flag in the ALU.)

Overflow in two's complement may occur, not when a bit is carried out
out of the left column, but when one is carried into it and no matching
carry out occurs. That is, overflow happens when there is a carry into
the sign bit but no carry out of the sign bit.

The OVERFLOW flag is the XOR of the carry coming into the sign bit (if
any) with the carry going out of the sign bit (if any). Overflow happens
if the carry in does not equal the carry out.

Examples (2-bit signed 2's complement binary numbers):

11
+01
===
00

- carry in is 1
- carry out is 1
- 1 XOR 1 = NO OVERFLOW


01
+01
===
10

- carry in is 1
- carry out is 0
- 1 XOR 0 = OVERFLOW!


11
+10
===
01

- carry in is 0
- carry out is 1
- 0 XOR 1 = OVERFLOW!


10
+01
===
11

- carry in is 0
- carry out is 0
- 0 XOR 0 = NO OVERFLOW

Note that this XOR method only works with the *binary* carry that goes
into the sign *bit*. If you are working with hexadecimal numbers, or
decimal numbers, or octal numbers, you also have carry; but, the carry
doesn't go into the sign *bit* and you can't XOR that non-binary carry
with the outgoing carry.

Hexadecimal addition example (showing that XOR doesn't work for hex carry):

8Ah
+8Ah
====
14h

The hexadecimal carry of 1 resulting from A+A does not affect the
sign bit. If you do the math in binary, you'll see that there is
*no* carry *into* the sign bit; but, there is carry out of the sign
bit. Therefore, the above example sets OVERFLOW on. (The example
adds two negative numbers and gets a positive number.)


twitter facebook me2day 요즘
따끈 따끈
따끈 따끈
06.02 19:14 | 참치2님 | 신고 | 수정 | 삭제
댓글 0
입력상자 늘리기
감사합니다.
감사합니다.
07.25 11:13 | donggoli님 | 신고 | 수정 | 삭제
댓글 0
입력상자 늘리기
잘보고가요^
잘보고가요^
08.04 14:11 | leejaemyou님 | 신고 | 수정 | 삭제
댓글 0
입력상자 늘리기
좋은정보 감사해요~^^
좋은정보 감사해요~^^
08.13 00:52 | jsd9399님 | 신고 | 수정 | 삭제
댓글 0
입력상자 늘리기
잘 보고 갑니다.
잘 보고 갑니다.
09.28 16:37 | nggag님 | 신고 | 수정 | 삭제
댓글 0
입력상자 늘리기
와우 소중한자료네요
와우 소중한자료네요
11.10 17:08 | Dong-Uk Kim님 | 신고 | 수정 | 삭제
댓글 0
입력상자 늘리기
감사합니다.^^
감사합니다.^^
11.13 13:57 | Lee Yongjoong님 | 신고 | 수정 | 삭제
댓글 0
입력상자 늘리기
감사합니다.
감사합니다.
12.02 15:38 | 원더보이님 | 신고 | 수정 | 삭제
댓글 0
입력상자 늘리기
감사합니다^^
감사합니다^^
02.07 18:44 | 리더사마님 | 신고 | 수정 | 삭제
댓글 0
입력상자 늘리기
감사 합니다.
감사 합니다.
02.17 02:08 | grayreaver님 | 신고 | 수정 | 삭제
댓글 0
입력상자 늘리기
댓글쓰기 - 로그인한 후 댓글작성권한이 있을 경우 이용하실 수 있습니다.

비밀번호 확인

댓글 등록시에 입력했던 비밀번호를 입력해 주세요.
26개(1/2페이지)
rss
어셈블리언어
번호 제목 작성자 작성일 조회
26 push 명령어 tip[2] 휘바골드 2013.02.22 1477
25 비베이용 강좌 2 kane0202 2012.12.23 2061
24 비베 6.0 기초강좌[2] kane0202 2012.12.23 2301
>> Carry VS Overflow Flag 개념 잡기.[10] 마플 2012.06.02 9212
22 [기초]간과하기 쉬운 것들...[27] 쿨러 2011.10.13 8502
21 [중급]어셈블리어의 CPU레지스터[17] 오타해커 2011.08.18 9438
20 [고급]ReaD Time Stamp Counter (RDTSC) 명령어[2] Sone 2010.02.03 9994
19 [고급]PC ASM첨부파일[25] 디코 2009.12.23 9215
18 [기초]어셈블리로 swap 함수![8] 룰루라라라 2010.07.17 9147
17 [기초]김병희님 강좌입니다.첨부파일[101] 공돌이pooh 2010.02.14 10994
16 [기초]LEA 명령어 강좌[9] 우준 2010.01.17 10238
15 [기초][PDF] 어셈블리어의 기초.첨부파일[81] 프로그래밍 2009.06.02 18365
14 [기초]8051 어셈블리언어[18] Mrsa 2009.04.02 7709
13 [기초]ASM 강좌첨부파일[61] Нyan™ 2008.04.21 9923
12 [기초]Pop 문 정리[12] EROS 2008.04.01 7944
11 [기초]Mov 문 정리[14] EROS 2008.04.01 7426
10 [기초]Call 문 정리[18] EROS 2008.04.01 8380
9 [기초]CMP 문 정리[16] EROS 2008.04.01 8393
8 [기초]Jxx 명령어 종합[26] EROS 2008.04.01 8960
7 [기초]8051 어셈블리언어 해석[2][26] Mrsa 2007.12.10 7757
처음페이지이전 10 페이지12다음 10 페이지마지막페이지