C H A P T E R

Chapter 2: 수의 체계

16
ㅔ

Chapter 2: 수의 체계

비트 작업

공부할 내용

★ 4개의 기본 비트 연산 명령

★ 비트 매스크

★ 특정 비트를 끄는 명령 : AND

★ 특정 비트를 켜는 명령: OR

★ 특정 비트를 보수로 바꾸는 명령: XOR

★ 바이트나 워드 전체를 보수로 만드는 명령: NOT

★ 특정 비트를 테스트하는 명령: TEST

★ 바이트나 워드내에서의 비트의 위치 변경: 쉬프트, 로테이트

★ 쉬프트 명령을 사용한 부호있는 수의 곱셈과 나눗셈

4개의 기본 비트 연산

□ 특정 비트를 끈다 (0으로 세트한다)

□ 특정 비트를 켠다 (1로 세트한다)

□ 특정 비트를 보수로 바꾼다 (0은 1로, 1은 0으로)

□ 모든 비트를 보수로 바꾼다

★이런 연산을 수행하는 명령은 각각 AND, OR, XOR과 NOT이다.

(형식)

AND     operand1, operand2

OR      operand1, operand2

XOR     operand1, operand2

NOT     operand

(설명)

- 각 오퍼랜드는 바이트나 워드일 수 있다.

- AND, OR와 XOR을 사용할 때, 두 오퍼랜드는 길이가 같아야 함.

첫째 오퍼랜드: 레지스터나 자료 항목일 수 있고

둘째 오퍼랜드: 레지스터, 자료항목, 또는 즉치일 수 있다.

- 이런 명령들은 첫째 오퍼랜드의 비트들을 변경시킨다.

예)

AND     AX, BX

OR       AL, VALUE

XOR     VALUE, DH

AND     DATA, 0001100111110110B

OR      AX, 3H

XOR     DL, 'a'

비트 매스크

★ AND, OR와 XOR 명령은 첫째 오퍼랜드에 있는 비트들을 변경함

- 둘째 오퍼랜드를 비트 매스크(bit mask), 매스크(mask)라고 함.

- 비트 매스크는 바이트나 워드 안에서 특정 비트를 가리운다.

가려지지 않은 비트들만이 켜지거나 꺼지거나 보수로 바뀜

예) 아래의 AND 명령이 사용하는 매스크는 0000111100001111B이다.

AND     AX, 0000111100001111B

AND     AX, 0F0FH  ; 16진수 매스크

<=>

LEFTOFF EQU     0000111100001111B; EQU 사용

AND     AX, LEFTOFF

특정 비트를 끄는 명령: AND

★ AND는 첫째 오퍼랜드의 특정 비트들을 끈다.

예) AL에 10010110B가 들어있다고 가정하고, 다음의 명령을 보자.

AND     AL, 11110000B

매스크: 11110000B

결과: AL에는 10010000B가 남는다.

예) 매스크가 모두 1이면 첫째 오퍼랜드의 비트는 전혀 변경되지 않음

AND     VALUE, 11111111B

★ AND가 가장 유용한 때

- 바이트나 워드 내의 특정 비트 1개를 끄려는 경우

AND     CX, 1111111111111110B

예) 숫자형 문자를 비압축 10진수로 변환하는 예

AND     AL, 00001111B

AND     AX, 0000111100001111B

AND     AX, 0F0FH

	그림 16-1				10개의 10진 자리수의 ASCII 코드와 비압축 10진 값

ASCII	30H  31H  32H  33H  34H  35H  36H  37H  38H  39H

비압축 10진수	00H  01H  02H  03H  04H  05H  06H  07H  08H  09H

equate를 다음과 같이 설정하면

CONVERT_ASCII  EQU	0F0FH

AND   AX, CONVERT_ASCII

특정 비트를 켜는 명령: OR

★ OR는 첫째 오퍼랜드의 특정 비트를 켠다.

예)  AL에 10010110B가 들어 있다고 가정하고, 다음의 명령을 보자

OR      AL, 11110000B

매스크: 11110000B

결과: AL에는 11110110B가 남는다.

★ 매스크가 모두 1이면 OR는 첫째 오퍼랜드의 모든 비트들을 켠다.

OR      BX, 1111111111111111B

★ 매스크가 모두 0이면 첫째 오퍼랜드의 비트는 모두 변경되지 않은 채 그대로 있다.

OR      VALUE, 00000000B

★ OR이 가장 유용한 때는 바이트나 워드내의 특정 비트 1개를 켤 때

OR      CX, 0000000000000001B

예)  비압축 10진수를 ASCII로 변환하는 예제

OR      AL, 00110000B

OR      AX, 0011000000110000B

OR      AX, 3030H

<=>

CONVERT_DECIMAL EQU    3030H

OR      AX, CONVERT_DECIMAL

특정 비트를 보수로 바꾸는 명령: XOR

★ XOR는 첫째 오퍼랜드의 특정 비트를 보수로 바꾼다.

예)  AL에 00111100B가 들어 있다고 가정하고, 다음의 명령을 보자.

XOR    AL, 11110000B

매스크: 11110000B

결과:  AL에는 11001100B가 남는다.

★ 매스크가 모두 1이면 XOR는 첫째 오퍼랜드의 모든 비트가 보수로

예) BX에 0011001100110011B가 들어 있다면 다음의 명령은

XOR    BX, 1111111111111111B

BX를 1100110011001100B로 바꾼다.

★ 매스크가 모두 0이면 첫째 오퍼랜드의 비트는 모두 변경되지 않음

XOR     VALUE, 00000000B

★ XOR이 가장 유용한 때는 바이트나 워드내의 특정 비트 한 개를 보수로 바꾸는 것이다.

XOR     CX, 0000000000000001B

★ 첫째는 □inclusive or□라고 하고, 둘째는 □exclusive or□라고 한다. XOR 명령 - exclusive or

OR  명령 - inclusive or

바이트 또는 워드 전체를 보수로 바꾸는 명령: NOT

★ NOT은 오퍼랜드가 1개이며, 이 오퍼랜드의 모든 비트를 보수로 바꾼다. 0은 1로 변경되고, 1은 0으로 변경된다.

예) AX에 0011001100110011B가 들어 있다면 다음의 명령은

NOT     AX

AX의 내용을 1100110011001100B로 바꾼다.

예)  VALUE가 11110000B를 갖는 바이트라면 아래의 명령은

NOT     VALUE

VALUE를 00001111B로 바꾼다.

특정 비트를 테스트하는 명령: TEST

(형식)

TEST    operand1, operand2

(설명)

- TEST는 첫째 오퍼랜드(operand1)를 검사하여 특정 비트가 켜져      있는지를 알아낸다.

- 첫째 오퍼랜드: 레지스터, 자료 항목

둘째 오퍼랜드: 레지스터, 자료 항목 또는 즉치일 수 있다.

- 둘째 오퍼랜드는 첫째 오퍼랜드의 어떤 비트가 테스트될 것인지를

지정하는 매스크 역할을 한다.

예)         TEST    AL, 11110000B

- AL의 오른편 4비트를 무시하고 왼편의 4비트만을 검사함

★ TEST는 오퍼랜드를 변경시키지 않는다. 대신에 TEST는 오퍼랜드를 검사하고 나서 검사 결과를 제로 플래그(ZF)에 나타낸다.

지정된 비트 중에서 어떤 것이라도 켜져 있었으면 ZF는 0으로 클리어되고, 지정된 비트 중의 어느 것도 켜져 있지 않으면 TEST는 ZF를 1로 세트한다.

예)

TEST    AL, 11110000B

JNZ      L1

예)

; REPEAT UNTIL (bit 3 of AL is turned ON)

;   call GET_INPUT

L1:

CALL    GET_INPUT

TEST    AL, 00001000B

JZ       L1

예)

; REPEAT UNTIL (bit 3 of AL is turned OFF)

;   call GET_INPUT

L1:

CALL      GET_INPUT

TEST      AL, 00001000B

JNZ        L1

바이트나 워드 내에서의 비트의 위치 변경

(형식)

opcode  operand, count

예)

SHL     VALUE, 4

예에 대한 설명)

- 첫째 오퍼랜드: 레지스터 또는 자료 항목임. (바이트 또는 워드)

- 각 명령이 하는 일은 첫째 오퍼랜드에 있는 비트들을 왼편으로

또는 오른편으로 쉬프트(shift)하는 것이다. 옮겨갈 자리수는

둘째 오퍼랜드의 값에 나타나 있다 (카운트).

	표 16-1			비트의 위치를 변경시키는 명령

이름	의미
SHL SAL SHR SAR ROL ROR RCL RCR	왼쪽으로 쉬프트하라 왼쪽으로 산술 쉬프트 (arithmetic shift) 하라 오른쪽으로 쉬프트하라 오른쪽으로 산술 쉬프트 하라 왼쪽으로 로테이트하라 오른쪽으로 로테이트하라 캐리와 함께 왼쪽으로 로테이트하라 캐리와 함께 오른쪽으로 로테이트하라

★ 카운트를 지정하는 방법

(1) 0과 31 사이의 즉치를 사용할 수 있다.

SHL     AX, 5

(2)  CL 레지스터를 사용: 0-31 사이의 값

MOV     CL, 5

SHL     AX, CL

기본적인 쉬프트 명령: SHL과 SHR

★ SHL과 SHR 명령은 비트들을 각각 왼쪽으로, 또는 오른쪽으로 쉬프트한다. 밖으로 나가게 된 비트들은 잃게 된다. 그러나 밖으로 나간 비트 중에서 마지막 것은 항상 캐리 플래그(CF)에 남는다.

예) DL이 11001100이고 3비트 오른쪽으로 쉬프트하면, 오른편의 100을 잃게 됨. 마지막으로 쉬프트된 1은 CF에 있음

1100	1100

★ 바이트나 워드가 쉬프트될 때, 비트들을 잃게 될 뿐아니라 채워야 되는 공간도 생긴다. SHL과 SHR은 이 공간을 0으로 채운다.

예) DL이 아래와 같고

1100	1100

SHL DL, 3

0001	1001

1

CF

★ 왼편으로 쉬프트할 때는 오른쪽 끝의 비트들이 0으로 채워진다.

예) DL이 아래와 같은 상태에서

1100	1100

SHL     DL, 3

0

0110	0000

CF

SHL과 SHR의 용도

★ SHL과 SHR은 두 가지 중요한 용도를 갖는다. 첫째, 바이트나 워드의 한 부분을 고립(isolate)시키는데 사용된다.

예) AL의 비트 3, 4, 5를 고립시켜서 이들을 레지스터의 오른편 끝으로 옮기려면

7654      3210    ← 비트번호

??xx	x???

이렇게 만들려고 하는 것이다.

7654      3210    ← 비트번호

0000	0xxx

(할일) 3, 4, 5비트를 제외한 비트를 0으로 만들고 나서, AL을 오른쪽 끝      의 3비트로 쉬프트하면 된다.

AND     AL, 00111000B

SHR     AL, 3

(다른 방법)

AL을 왼쪽으로 두 자리 쉬프트한 후, 오른쪽으로 5자리 쉬프트한다.

SHL     AL, 2

SHR     AL, 5

★ SHL과 SHR의 두 번째 중요한 용도는 2의 거듭제곱으로 곱하거나 나누는 일을 할 때이다.

00000101B (5) → 00010100B (20)

- 바이트나 워드를 n자리만큼 왼쪽(오른쪽)으로 쉬프트하는 것은 그 값에 2n을 곱하는 (나누는) 셈이다.

예)     SHL     BX, 4

SHR    VALUE, 2

★ 물론, 곱셈이나 나눗셈에 항상 MUL이나 DIV를 사용할 수 있지만 쉬프트를 사용하면 훨씬 빠르게 계산을 할 수 있다.

	표 16-2			곱셈과 나눗셈을 할 때 쉬프트해야 하는 자리수

곱하거나 나눌 수   □   □ 쉬프트 할 자리수

2    1

4    2

8    3

16    4

32    5

64    6

128    7

256    8

512    9

1024   10

쉬프트를 사용한 부호 있는 수의 곱셈과 나눗셈:

SAL과 SAR

★ 부호있는 수를 오른쪽으로 쉬프트(나눗셈)할 때 SHR을 사용하면,

왼쪽 끝의 빈 공간은 0으로 채워져서, 계산 결과가 틀리게 된다.

(해결책) 부호있는 수를 오른쪽으로 쉬프트할 때는 그 숫자가 양수이면 왼쪽의 공간을 0으로 채우고, 음수이면 1로 채운다.

====> SAR 명령

예)

SAR  AL,2

0000	1111

→

0000	0011

예)

SAR   BL,2

1111	0001

→

1111	1100

★ 부호있는 수를 왼쪽으로 쉬프트할 때는 (곱할 때는) 오른편에 생기는 공간을 항상 0으로 채우므로, SAL은 SHL과 같다.

로테이트 명령: ROL, ROR, RCL, RCR

★ 로테이트(rotate) 명령

- 쉬프트 명령처럼 비트를 이동시킨다.

- 차이: 한쪽 끝으로 비트가 빠져 나가면 그 비트는 다른 편 끝으로

쉬프트되어 들어온다.

- 마지막으로 쉬프트되어 나간 비트는 캐리 플래그(CF)에 복사됨

★ ROR(rotate right): 은 비트들을 오른편으로 이동시킨다.

ROL(rotate left): 비트들을 왼편으로 이동시킨다.

예)

ROR   AL,1

0000	1111

→

1000	0111

예)

ROL   AL,5

0000	1111

→

1110	0001

예) AL에 저장되어 있는 바이트의 왼쪽 반과 오른쪽 반을 교환한다.

ROL     AL, 4

ROR     AL, 4

예)  AX에 저장되어 있는 워드의 왼쪽 반과 오른쪽 반을 교환한다.

ROL     AX, 8

ROR     AX, 8

★ RCR(rotate with carry right),  RCL(rotate with carry left) 명령

- ROR, ROL과 비슷하다.

- 차이점: CF가 로테이트하는 과정에서 1개의 여분의 비트로써

고려됨

예)         RCR     AL, 1

AL       CF           AL      CF

0011	1100	1

→

1001	1110	0

예)         RCL     AL, 3

CF       AL          CF      AL

0	0011	1100

→

1	1110	0000