C H A P T E R

Chapter 2: 수의 체계

10
ㅔ

제어 흐름

공부할 내용

★ 제어 흐름(control flow)

★ 코드 세그먼트 내에서의 레이블 정의와 사용

★ 플래그 레지스터, 상태 플래그, 제어 플래그

★ 제어 플래그의 값을 변경하는 명령

★ 조건부 점프 명령

★ 플래그와 레지스터를 테스트하는 조건부 점프

★ 두 숫자를 비교하는 명령

★ 비교 후에 사용되는 조건부 점프

★ 무조건 점프

★ 루프 명령

코드 세그먼트 내에서의 레이블

★ 레이블은 코드 세그먼트에서 이정표(marker) 역할을 하는데 쓰임

(정의) name    LABEL   type

★ 레이블의 형: NEAR, FAR

L1        LABEL   NEAR

ENTRY   LABEL   FAR

★ 대부분의 레이블이 near이므로 다음과 같이 간단히 정의할 수 있다.

(즉, 콜론으로 끝나는 이름은 near 레이블이다)

name:

예)    L1:

예)    TESTAX:

CMP     AX, 0

레이블의 이름 결정 지침

★ 이름은 최대 31글자까지 될 수 있다.

PROCESS_NEXT_NUMBER:

PRINT_SUM:

READ_THE_NEXT_CHARACTER:

L1:

★ 권장사항

(1) 가까운 곳에서 사용되는 레이블들의 이름은 짧게

(2) 따로 떨어져 있는 레이블은 설명적이고 긴 것으로 만든다.

★  레이블을 사용하는 예제

고급 언어 프로그램:

IF (AX = 0  and BX = 0) THEN CX := 10 ELSE CX := 20

어셈블리 언어 프로그램:

; if (AX = 0 and BX = 0) CX <-- 10

; else                   CX <-- 20

CMP     AX, 0

JNZ     L1

CMP     BX, 0

JNZ     L1

MOV     CX, 10

JMP     L2

L1:

MOV     CX, 20

L2:

플래그 레지스터

★ 플래그 레지스터(flags register)는 다른 레지스터들과 달리, 16비트 모두가 독립적인 요소로 간주되고 취급된다.

★ 16비트 중에서

상태 플래그(status flag) - 6개

제어 플래그(control flag) - 3개

남은 7개는 리얼 모드에서는 사용되지 않는다.

★ 상태 플래그: 특정 명령으로부터 생성된 결과를 나타낸다.

제어 플래그: 프로세서의  동작을 제어한다.

★ 플래그 ← 1  (플래그를 세트한다.)

플래그 ← 0  (플래그를 클리어한다.)

	15	14	13	12	11	10	9	8	7	6	5	4	3	2	1	0
					OF	DF	IF	TF	SF	ZF		AF		PF		CF

상태 플래그
약어	이름
AF CF OF PF SF ZF	보조 캐리 플래그(Auxiliary carry flag) 캐리 플래그(Carry flag) 오버플로우 플래그(Overflow flag) 패리티 플래그(Parity flag) 사인 플래그(Sign flag) 제로 플래그(Zero flag)
제어 플래그
약어	이름
DF IF TF	디렉션 플래그(Direction flag) 인터럽트 플래그(Interrupt flag) 트랩 플래그(Trap flag)

상태 플래그

★ 상태 플래그의 값을 변경하는 명령은 많이 있으며, 대부분의 명령은 1개 이상의 플래그 값을 변경한다. 일반적으로 상태 플래그는 부호 있는 수(양수와 음수), 부호 없는 수(양수뿐임), 10진수 산술 연산에 사용된다.

□ 제로 플래그(zero flag) : 연산의 결과가 0이 아닐 때 세트된다

□ 사인 플래그(sign flag) : 연산의 결과가 음수일 때 세트된다.

□ 오버플로우 플래그(overflow flag) :

- 부호 있는 수의 연산에 사용된다.

- 연산의 결과가 너무 길 때 세트된다.

□ 캐리 플래그(carry flag) :

- 부호 없는 수의 연산에 사용된다.

- 연산의 결과가 너무 길 때 세트된다.

□ 보조 캐리 플래그(auxiliary carry flag) :

- 10진수 연산에 사용된다.

- 10진수 덧셈이나 뺄셈을 할 때 보정이 필요할 때 세트된다.

□ 패리티 플래그(parity flag) :

- 연산의 결과에 1의 값을 갖는 비트가 짝수 개일 때 세트된다.

상태 플래그 값을 변경하는 명령: STC, CLC, CMC

STC	:	set carry flag

CLC	:	clear carry flag

CMC	:	complement carry flag

★ 이 명령들의 용도

(1) CF는 프로시저의 에러 조건을 나타내는 데 사용된다.

(2) 특정 로테이션 명령(RCL과 RCR 명령)은 CF를 연산의 일부분

으로 사용한다. 따라서 RCL이나 RCR을 사용하기 전에 특정 값

을 CF에 넣기도 한다.

제어 플래그

★ 제어 플래그는 프로세서의 동작을 제어하는데 사용된다. 제어 플래그는 앞으로 실행될 명령의 동작을 변경한다.

□ 디렉션 플래그(direction flag) : 문자열 관련 명령에 의하여  사용된다.

DF=0 이면, 문자열은 전진하면서 처리된다.

DF=1 이면, 문자열은 역방향으로 처리된다.

□ 인터럽트 플래그(interrupt flag) : 외부 장치, 내부 장치 또는 특정 프로그램이 프로세서의 어텐션(attention)을 받으려 할 때 인터럽트를 건다.

IF = 1 이면, 프로세서는 모든 인터럽트를 인식한다.

IF = 0 이면, 프로세서는 외부 장치로부터 들어오는 인터럽트를무시한다(IF가 1로 다시 세트될 때까지).

□ 트랩 플래그(trap flag) : 프로그램이 프로세서를 특이한 상태에서 작동하도록 하여 각 명령이 실행될 때마다 지정된 프로시저를 호출하도록 해준다.

TF = 1 이면, 프로세서는 각 명령을 실행하고 나서 (인터럽트를 걸어) 특정한 프로시저를 호출한다.

TF = 0 이면, 프로세서는 보통 때와 같이 작동한다.

제어 플래그의 값을 변경하는 명령:

STD, CLD, STI, CLI

STD	:	set direction flag

CLD	:	clear direction flag

STI	:	set interrupt flag

CLI	:	clear interrupt flag

조건부 점프 명령

★ 조건부 점프(conditional jump):  특정 조건이 참이 될 때만 실행되는 점프이다.

(형식)	Jxxx    label

(예) ; if CX is not equal to 0, set it to 10

JCXZ    L1

MOV     CX, 10

L1:

플래그와 레지스터를 테스트하는 조건부 점프

★ 종류

(1) 플래그의 값에 따라 점프하는 조건부 점프 명령이 10개

(2) 레지스터(CX)의 값에 따라 점프하는 조건부 점프 명령이 1개

□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□

약어	의미

□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□

Z	제로 플래그

S	사인 플래그

O	오버플로우 플래그

C	캐리 플래그

P	패리티 플래그

N	반대(Not)

□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□

				플래그를 테스트하는 조건부 점프 명령

연산 코드	의미
JZ JNZ JS JNS JO JNO JC JNC JP (JPE) JNP (JPO)	ZF 가 1 로 세트되었으면 점프하라 ZF 가 0 으로 클리어되었으면 점프하라 SF 가 1 로 세트되었으면 점프하라 SF 가 0 으로 클리어되었으면 점프하라 OF 가 1 로 세트되었으면 점프하라 OF 가 0 으로 클리어되었으면 점프하라 CF 가 1 로 세트되었으면 점프하라 CF 가 0 으로 클리어되었으면 점프하라 PF 가 1 로 세트되었으면 점프하라 PF 가 0 으로 클리어되었으면 점프하라

				CX 레지스터의 값을 테스트하는 조건부 점프

연산 코드	의미
JCXZ	CX가 0 이면 점프하라

두 숫자를 비교하는 명령: CMP

(형식)       CMP     value1, value2

CMP 명령 다음에는 대부분의 경우에 다음에 설명될 조건부 점프

명령이 뒤따른다.

(예)         CMP     AX, BX

CMP     AX, TOTAL

CMP	AX, 0

CMP     TOTAL, AX

CMP     TOTAL, 0

★ 제약점

(1) (메모리에 있는) 두 자료 항목을 비교하는 것은 허용되지 않는다.

(2) 부호 없는 수끼리 비교하거나 부호 있는 수끼리 비교하여야 한다.

(3) 비교 대상이 되는 두 수는 그 길이가 같아야 한다.

비교 후에 사용되는 조건부 점프

★ 종류:

(1) 부호 있는 수에 사용되는 조건부 점프

(2) 부호 없는 수에 사용되는 조건부 점프

□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□

약어	의미

□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□

N	아니다 (Not)

E	같다 (Equal)

G	크다 (Greater than)

L	작다 (Less than)

B	아래에 있다 (Below)

A	위에 있다 (Above)

□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□

				부호 있는 수에 사용되는 조건부 점프

프로세서	명령어 집합의 크기
JL (JNGE) JG (JNLE) JLE (JNG) JGE (JNL) JE JNE	작으면 (크거나 같지 않으면) 점프하라 크면 (작거나 같지 않으면) 점프하라 작거나 같으면 (크지 않으면) 점프하라 크거나 같으면 (작지 않으면) 점프하라 같으면 점프하라 같지 않으면 점프하라

				부호 없는 수에 사용되는 조건부 점프

프로세서	명령어 집합의 크기
JB (JNAE) JA (JNBE) JBE (JNA) JAE (JNB) JE JNE	아래에 있으면 (위에 있거나 같지 않으면) 점프하라 위에 있으면 (아래에 있거나 같지 않으면) 점프하라 아래에 있거나 같으면 (위에 있지 않으면) 점프하라 위에 있거나 같으면 (아래에 있지 않으면) 점프하라 같으면 점프하라 같지 않으면 점프하라

예) 부호 있는 수 TOTAL이 0보다 작으면 여러 명령문을 건너뛴다.

CMP     TOTAL, 0

JL        L1

-------   instructions to be skipped   --------------

L1:

또는

CMP     TOTAL, 0

JNGE    L1

-------   instructions to be skipped   --------------

L1:

예) 부호 없는 수 SUM이 AX의 부호없는 수의 값보다 작으면 점프하라.

CMP     SUM, AX

JB      L2

-------   instructions to be skipped   --------------

L2:

예) DI의 값이 VALUE라는 변수의 값보다 크거나 같으면 점프

DI와 VALUE에는 부호 있는 수가 저장되어 있다고 가정하자.

CMP     DI, VALUE

JGE     L3

-------   instructions to be skipped   --------------

L3:

예) AH 레지스터의 값이 DH의 값보다 크거나 같을 때 점프하라

AH와 DH에는 부호 없는 수가 있다고 가정하자.

(JGE 대신에 JAE를 사용한다).

CMP     AH, DH

JAE     L4

------   instructions to be skipped   --------------

L4:

모든 조건부 점프 명령의 참조표

연산 코드	플래그/레지스터에 세트되어 있는 값
JA (JNBE) JAE (JNB) JB (JNAE) JBE (JNA) JC JCXZ JE JG (JNLE) JGE (JNL) JL (JNGE) JLE (JNG) JNA (JBE) JNAE (JB) JNB (JAE) JNBE (JA) JNC JNE	CF=0 이고 ZF=0 CF=0 CF=1 CF=1 이거나 ZF=1 CF=1 CX=0 ZF=1 ZF=0 이고 SF=OF SF=OF SF=1 이거나 OF=1 둘 다 1 이면 안 됨 ZF=1 이거나 (SF=1 이거나 OF=1 둘 다 1 이면 안 됨) CF=1 이거나 ZF=1 CF=1 CF=0 CF=0 이고 ZF=0 CF=0 ZF=0

연산 코드	플래그/레지스터에 세트되어 있는 값
JNG (JLE) JNGE (JL) JNL (JGE) JNLE (JG) JNO JNP JNS JNZ JO JP JPE JPO JS JZ	ZF=1 이거나 (SF=1 이거나 OF=1 둘 다 1 이면 안 됨) SF=1 이거나 OF=1 둘 다 1 이면 안 됨 SF=OF ZF=0 이고 SF=OF OF=0 PF=0 SF=0 ZF=0 OF=1 PF=1 PF=1 PF=0 SF=1 ZF=1

무조건 점프: JMP

★ 무조건 점프(unconditional jump)는 항상 실행되는 점프이다.

(형식)     JMP     label

(예)

JMP     L1

JMP     FINISHED_DISPLAY

JMP     TABLE[SI]

★ 용도

(1) 특정 조건이 만족되었을 때, 실행되지 않을 명령들을 건너 뛸 때

(2) 루프를 형성하기 위하여 역방향으로 점프할 때

점프 명령에서의 주소 사용 규칙

★ JMP를 사용할 때 점프할 주소

- 동일한 코드 세그먼트에 있는 주소(near)이어도 되고,

- 다른 코드 세그먼트의 주소(far)이어도 된다.

★ 조건부 점프가 사용하는 주소

- near 레이블로만 점프할 수 있다.

- 그 레이블은 현재의 명령문으로부터 127바이트 내에 있어야 한다.

- 이유 : 조건부 점프가 기계어로 변환될 때 레이블의 주소가 1바이트에 들어가도록 프로세서가 설계되어 있기 때문

예)   ; if data is invalid (CF = 1) then execute error section

JC      INVALID_DATA

예)   ; if data is invalid (CF = 1) then execute error section

JNC     L1

JMP     INVALID_DATA

L1:

명령문 시퀀스를 반복하는 명령: LOOP

★ 루프(loop) - 반복적으로 실행되는 명령문의 시퀀스(sequence)

★ LOOP 명령 - 지정된 횟수만큼 실행될 루프를 만드는데 사용된다.

(형식)	LOOP    label

(루프의 구조)

MOV     CX, loop-count

label:

---   statements to be executed   -----

LOOP    label

(하는 일) LOOP 명령은 CX에서 1을 뺀다. 그리고 나서 CX가 0이

아니면 LOOP는 지정된 레이블로 점프한다.

예)	MOV     CX, 100

L1:

---   statements to be executed   ----

LOOP    L1

예)  100개의 숫자를 더하는 예

TABLE   DW      100 DUP(?)

............

; set AX to the sum of 100 numbers, stored

;  as words in TABLE

MOV     AX, 0

MOV     SI, 0

MOV     CX, 100

L1:

ADD     AX, TABLE[SI]

ADD     SI, 2

LOOP    L1

비교를 사용하는 루프: LOOPE와 LOOPNE

★ LOOPE와 LOOPNE는 CX에서 1을 빼고 나서 CX가 0이 아닐 때만 점프한다. 그리고, LOOPE는 바로 위에서 실행한 비교에서 두 오퍼랜드가 서로 같도록 요구한다. LOOPNE는 두 오퍼랜드가 같지 않도록 요구한다.

예)  TABLE   DW      100  DUP(?)

..............

; search a table of 100 words for the value -1

MOV     SI, -2

MOV     CX, 100

L1:

ADD     SI, 2

CMP     TABLE[SI], -1

LOOPNE  L1

예)  ; search a table of 100 words for a value not equal to -1

MOV     SI, -2

MOV     CX, 100

L1:

ADD     SI, 2

CMP     TABLE[SI], -1

LOOPE   L1

				루프 명령

연산 코드	의미	플래그/레지스터의 값
LOOP LOOPE(LOOPZ) LOOPNE(LOOPNZ)	루프를 실행하라 같으면 (0 이면) 루프를 실행하라 같지 않으면 (0 이 아니면) 루프를 실행하라	CX가 0 이 아님 CX가 0 이 아니고 ZF=1 CX가 0 이 아니고 ZF=0