플래그 래지스터&디버거
2025. 4. 27. 21:23ㆍ어셈블리 프로그래밍
프로세서 상태와 플래그 레지스터
- 프로세서가 명령어를 실행할 때마다 프로세서의 상태도 변화한다.
- 명령어 실행에 따른 프로세서 상태 변화를 나타내기 위해서 플래그 레지스터를 제공한다!
- 플래그 레지스터의 각 비트 명령어 실행→하드웨어 작동 여부 결정

| 비트 | 이름 | 기호 | |
| 상태 플래그 | 0 | 캐리 플래그 | CF |
| 2 | 패리티 플래그 | PF | |
| 4 | 보조 캐리 플래그 | AF | |
| 6 | 제로 플래그 | ZF | |
| 7 | 부호 플래그 | SF | |
| 11 | 오버플로우 플래그 | OF | |
| 제어 플래그 | 8 | 트랩 플래그 | TF |
| 9 | 인터럽트 플래그 | IF | |
| 10 | 디렉션 플래그 | DF |
- 상태 플래그: 명령어 실행으로 인한 프로세서의 상태를 나타냄
- 제어 플래그: 인터럽트 등의 프로세서의 동작을 제어하기 위해 사용
상태 플래그
- 패리티 플래그: 직렬 통신의 패리티 비트를 만들기 위해 사용
- 보조 캐리 플래그: 10진수 연산의 캐리 발생 여부를 나타내기 위해 사용
- 하지만 위의 두 가지 플래그는 최근 프로세서에서 사용하지 않고 나머지 4개의 플래그로 제공함!
캐리 플래그(CF)
부호 없는 수의 연산 결과가 목적지 오퍼랜드에 저장할 수 없을 정도로 큰 수를 생성하였는지 나타냄.
ex)
부호 없는 수의 덧셈에서 최상위 비트의 자리 올림이 있거나 뺄셈에서 자리 빌림이 있으면 CF를 1로 아니면 0으로 지정
패리티 플래그(PF)
연산 결과로 하위 바이트에 있는 1의 개수가 짝수이면 1이 되고 아니면 0으로 지정
ex)
FFFFH(11111111)은 1의 개수가 짝수이므로 PF는 1로 지정
보조 캐리 플래그(AF)
덧셈에서 3번 비트로부터 자리올림이 발생하거나 뺄셈에서 3번 비트로 자리 빌림이 있으면 AF는 1이 된다. 초기 컴퓨터에서는 10진수 연산을 위해서 사용함.
제로 플래그(ZF)
연산 결과가 0이면 ZF가 1이 되고 아니면 0이 된다.
부호 플래그(SF)
부호 있는 수의 연산 결과가 0이거나 양수이면 SF는 0 음수이면 1이 된다. 최상위 비트가 부호 비트를 나타내기에 부호 플래그와 동일한 값을 가진다! (최상위 비트=SF 플래그)
오버플로우 플래그(OF)
부호 있는 수의 연산 결과가 정상적인 표현 범위를 벗어났는지 나타내기 위해 사용한다. 범위를 벗어나는 경우 1, 아니면 0이다.
- 최근 프로세서는 CF, ZF, SF, OF만을 활용하여서 상태 플래그에 변화를 준다.
- MOV나 XCHG명령어는 데이터 전송에 의해 레지스터나 메모리 변수의 내용은 변하지만 상태 플래그는 변하지 않는다.
제어 플래그
트랩 플래그(TF)
프로세서를 특정 상태에서 동작하도록 지시하기 위해서 사용된다. TF가 1이면 8086 프로세서는 각 명령어 실행 후 인터럽트를 걸어 특정 프러시저가 호출되도록 해준다. TF가 0이면 프로세서는 보통 때와 같이 동작한다.
인터럽트 플래그(IF)
8086외부 및 내부 장치에서 발생한 인터럽트를 허용하느냐를 설정하기 위해 사용된다. IF가 1이면 인터럽트를 허용하고 IF가 0이면 인터럽트를 허용하지 않는다.
디렉션 플래그(DF)
문자열과 관련된 명령의 수행 방식을 지정한다. DF가 0이면 문자열 관련 명령어가 메모리 주소가 증가하는 방향으로 문자열을 처리하고 1이라면 감소하는 방향으로 처리한다.
산술 오버플로우
- 레지스터나 메모리 변수들은 크기가 제한되어 있다.
- 레지스터의 메모리를 벗어나면 오버플로우가 발생하게 된다.
- 이를 확인하기 위해서 CF와 OF를 확인하면 알 수 있다.
부호 없는 수의 오버플로우
- 8비트의 표현 범위: 0~255(00H~0 FFH)
- 16비트의 표현 범위: 0~65535(0000H~0FFFFH)
- 부호 없는 수의 크기가 255이고 16비트의 부호 없는 수의 최대 크기는 65535이다.
- 만약 덧셈이나 뺄셈에서 최상위 비트로부터 자리 올림이 있거나 뺄셈에서의 자리 빌림이 있으면 CF는 1이 된다.
ex)
ADD AX(0 FFFFH), BX(0001H) = 10000H
-캐리가 발생하였고 AX에는 0이 저장된다.
-즉, 위에서 오버플로우가 발생함을 볼 수 있다.
SUB AX(4000H), BX(8000H) = C000H
-작은 수에서 큰 수를 빼면서 최상위 비트로부터 자리 빌림이 발생한다.
-이로 인해서 오버플로우가 발생한다.
ADD AX(FFH), 01H = 100H
-캐리가 발생하여서 CF=1이 된다.
이로 인해서 오버플로우가 발생한다.
부호 있는 수의 오버플로우
- 8 비트 부호 있는 수의 표현 범위: 80H(-127) 부터 7FH(127)
- 16비트 부호있는 수의 표현 범위: 8000H(-32768)~7 FFFH(32767)
- 범위를 벗어나게 된다면 연산 결과의 부호가 바뀌게 되고, OF는 1이 된다.
- 즉, 부호 있는 수의 연산에서는 OF=1이면 오버플로우가 발생함을 확인할 수 있다.
ADD AX(4000H), BX(4000H) = 8000H(음수)
-양수 + 양수 = 음수
-OF가 1이고 오버플로우가 발생함을 확인할 수 있다.
SUB BX(D000H), CX(6000H) = 7000H(양수)
-음수 - 양수 = 양수
-(-양수)를 하면 음수가 나와야 하는 데 양수가 나왔기 때문에 오버플로우가 발생하였다.
SUB AL(7FH), BL(80H) = FFH(음수)
-양수-음수=음수
-(-양수)를 하게 된다면 양수가 나와야 하는 데 음수가 나왔기 때문에 오버플로우가 발생하였다.
| 연산 | A | B | 결과 |
| 덧셈 | 양수 | 양수 | 음수 |
| 덧셈 | 음수 | 음수 | 양수 |
| 뺄셈 | 양수 | 음수 | 음수 |
| 뺄셈 | 음수 | 양수 | 양수 |
명령어 실행과 플래그 영향
- MOV, XCHG 명령어는 데이터 전송 명령어이기 때문에 상태 플래그의 영향을 받지 않는다.
- ADD, SUB 명령어는 연산 결과에 따라서 모든 상태 플래그가 영향을 받는다.
- INC, DEC 명령어는 CF를 제외한 모든 상태 플래그가 영향을 받는다.
- NEG 명령어는 모든 상태 플래그 비트가 영향을 받는다.
- 연산 결과가 0이 아니면 CF가 1이 되고 오퍼랜드가 8000H이거나 80H 이면 OF가 1이 된다.
ex)
4.1
MOV AX,3 FFFH => INC AX => ADD AX, AX => NEG AX => DEC AX
MOV AX, 3FFFH
-MOV연산자는 플래그에 아무런 영향을 주지 않는다. CF=0, SF=0, ZF=0, OF=0
INC AX
-AX는 4000H가 되지만 플래그 레지스터에는 변화가 없다.
ADD AX,AX
-AX+AX=8000H가 되기 때문에 부호가 음수로 변하였기 때문에 SF=1이고, 오버플로우가 발생하기 때문에 OF=1이 되고 나머지는 유지된다.
NEG AX
-8000H의 NEG 연산은 다음과 같이 할 수 있다.
-8000H = 1000 0000 0000 0000(2진수)이고 먼저 1의 보수를 취하면 0111 1111 1111 1111이고 2의 보수는 1을 더하면 구할 수 있기 때문에 0111 1111 1111 1111 + 1 = 1000 0000 0000 0000 이 나오게 된다.
-CF 같은 경우에는 0-8000H를 하였기 때문에 자리빌림이 발생하기 때문에 CF=1이 된다.
-결과는 8000H로 동일한 결과가 나오기 때문에 CF=0, SF=1, OF=1, ZF=0이 나온다.
DEC AX
-7 FFFH가 나오게 된다.
-즉, 음수-1(양수) = (양수) 이므로 오버플로우가 발생하기 때문에 OF=1이고, 최상위 비트에서 자리 내림이 발생해서 양수가 되기 때문에 CF=1이다.
-나머지는 0이다.
ex)
4.2
MOV BL, 80H => ADD BL, BL => DEC BL => SUB BL,7FH => NEG BL
MOV BL,80H
-아무런 변화가 없음
ADD BL, BL
-BL+BL=100H이므로 0이 저장된다.
-ZF=1이고, 오버플로우가 발생하였기 때문에 OF=1이고 자리 빌림이 발생하였기 때문에 CF=1이 나온다.
-SF=0
DEC BL
-BL-1을 하면 FFH가 나오게 되고 부호가 변하였기 때문에 SF=1이 된다.
-그리고 자리 빌림이 발생하였기 때문에 CF=1이 된다.
-OF=0, ZF=0이 된다.
SUB BL,7FH
-SUB BL, 7FH는 80H는 0이기 때문에 SF=1이다.
-음수-양수=음수이기 때문에 OF=0이다.
-나머지는 0으로 유지된다.
NEG BL
-80H는 NEG연산을 해주면 80H가 된다.
-즉 CF=1이 되고, SF=1이고, 0이 아니기 때문에 ZF=0이고 오퍼랜드가 80H이므로 1이 된다.
연습 문제
4.1
MOV BX,4000H => ADD BX, BX => SUB BX,0 FFFFH => DEC BX => NEG BX => ADD BX, 8000H
MOV BX, 4000H
-모든 상태 플래그가 0이다.
ADD BX,BX
-BX + BX = 8000H(음수) 이므로 SF와 OF가 1이 된다.
-나머지는 0으로 유지된다.
SUB BX, 0FFFFH
-BX - 0FFFFH = 8001H가 나오게 된다.
-자리 빌림이 발생하였기 때문에 CF=1이고, 음수 이기 때문에 SF=1이다.
-나머지는 0으로 이다.
DEC BX
-8000H이기 때문에 CF는 unchanged로 지정된다.
-SF는 음수이기 때문에 1이다.
-나머지는 0으로 유지된다.
NEG BX
-2의 보수를 구한다면 8000H로 그대로 유지된다.
-자리 빌림이 발생하기 때문에 CF=1이고, SF=1로 유지된다.
-0-8000H는 양수-양=음수이기 때문에 OF=1이 된다.
-나머지는 0으로 유지된다.
ADD BX, 8000H
-BX는 10000H이기 때문에 BX에는 0이 저장된다.
-CF=1이고, OF=0이고, SF=0, ZF=1이 나오게 된다.
4.2
MOV AX, 8000H => SUB AX, 4000H => NEG AX => ADD AX, AX => DEC AX
MOV AX, 8000H
-아무런 변화가 없다.
SUB AX,4000H
-음수-양수=양수이기 때문에 OF=1이 나오게 된다.
-그리고 자리빌림이 발생하기 때문에 CF=1이 된다.
-나머지는 0으로 설정된다.
NEG AX
-0100 0000을 2의 보수법으로 구한다면 1100 0000이 된다.
-즉 최상위 비트 자리 올림이 발생하기 때문에 CF=1이고 음수이기 때문에 SF=1이다.
-나머지는 0으로 설정된다.
ADD AX,AX
-C000H + C000H는 1100 0000 + 1100 0000 = 1 1000 0000이 되고 8000H 가 저장된다.
-자리올림이 발생해서 CF=1이고, SF는 1이 된다.
-나머지는 0으로 지정된다.
DEC AX
-AX는 7FFFH는 양수이기 때문에 음수 - 양수 = 양수 이기 때문에 OF가 1이 된다.
-CF는 unchanged 상태로 지정된다.
-나머지는 다 0으로 지정된다.
'어셈블리 프로그래밍' 카테고리의 다른 글
| 조건문 구조(2) (0) | 2025.05.22 |
|---|---|
| 조건문 구조 (0) | 2025.05.22 |
| 문자 입출력 (0) | 2025.04.13 |
| 8086 어셈블리 언어 (0) | 2025.04.04 |
| 8086 프로세서 (0) | 2025.03.25 |