C H A P T E R

Chapter 2: 수의 체계

8
ㅔ

자료의 정의

공부할 내용

★ 상수와 변수

★ 자료 정의 지시어

★ 반복되는 값의 정의

★ 문자, 숫자, 오프셋의 정의

★ 이름없는 항목의 주소 지정

★ 속성, 속성을 사용하는 연산자, 산술 연산자

★ PTR 연산자

★ 레이블 지시어

★ EQU 지시어

★ 위치 카운터, ORG 지시어

상수와 변수

★ 프로그램에서 사용되는 자료 항목의 종류

- 상수(constant): 프로그램이 실행되는 동안에 동일한 값을 유지

- 변수(variable): 프로그램이 실행되는 동안에 값이 변할 수 있음.

예)

COST    DB      100   ; 상수

TOTAL   DB      ?     ; 변수

★  상수와 변수는 프로그램 안에서 논리적으로만 구별됨.

자료 정의 지시어

지시어	형	설명
DB DW DD DQ DT	BYTE WORD DWORD QWORD TBYTE	바이트 워드 더블워드 쿼드워드 10바이트

★ 더블워드 - 주소의 저장, 수학 코프로세서로 계산할 때 쓰임.

★ 더블워드, 쿼드워드, 10바이트 그룹 : 수학 코프로세서로 계산할 때 쓰임.

예) 바이트 변수와 워드 크기의 상수의 정의

TOTAL   DB      ?

ZERO     DW      0

예) 5바이트의 더블워드로 된 리스트의 정의

LIST    DD      ?, ?, ?, ?, ?

예) 10개의 1바이트짜리 숫자로 구성된 상수 TABLE의 정의

TABLE   DB    50, 100, 25, 75, 99, 104, 23, 45, 101, 87

★ 숫자를 표현할 때는 10진수, 16진수, 2진수 중의 어느 것을 써도 된다.

MIX     DW      100, 0FAEH, 1001101B

★ 상수에 초기값으로 문자들을 줄 수 있다.

STAR    DB      "*"

STAR    DB      '*'

반복되는 값의 정의

★ (형식) 반복 횟수 DUP(반복되는 값)

HYPHENS DB      35 DUP("-")

WLIST   DW      200 DUP(?)

★  DUP를 다른 DUP 안에 쓸 수 있다.

WTABLE  DW     10 DUP (5 DUP(0), 6, 7, 8, 9, 10)

자료 항목의 참조

★ 명령문이 자료 항목의 이름을 사용하면 그 이름이 나타내는 것은

그 자료 항목의 첫째 빌딩 블록의 오프셋이다.

예)  LIST    DB      ?, ?, ?    (오프셋 = 120H라고 하자)

MOV AH, LIST ∃ MOV AH, DS:120H

★ 한 자료 항목 안에서 뒤따르는 빌딩 블록을 참조하려면 그 변수의

이름에 적당한 값을 더하여 주소를 만들면 된다.

MOV     AH, LIST+1

예)    BLIST   DB      500 DUP(?)

첫째 바이트: BLIST,        둘째 바이트:  BLIST+1

50번째 바이트: BLIST+49,   187번째 바이트: BLIST+186

예)   WLIST   DW      500 DUP(?)

첫째 워드: WLIST,          둘째 워드: WLIST+2

셋째 워드: WLIST+4,        넷째 워드: WLIST+6

예)  더블워드, 쿼드워드, 10바이트 그룹으로 된 세 변수의 예

DLIST   DD      500 DUP(?)

QLIST   DQ      500 DUP(?)

TLIST   DT      500 DUP(?)

-- DLIST의 둘째 더블워드: DLIST+4

QLIST의 셋째 쿼드워드:  QLIST+16

TLIST의 13번째 10바이트 그룹: TLIST+120

★ 인덱스 레지스터를 써서 리스트의 원소를 처리

예)  DLIST[DI]

DI: 0, 4, 8, 12, 16, ...  가 되면

DLIST[DI] => DLIST+0, DLIST+4, DLIST+8, DLIST+12.....

DB 지시어를 사용한 문자의 정의

★ DB 지시어는 바이트로부터 형성된 자료 항목을 정의한다.

- DB ∃ □define bytes□

- 1 바이트에 저장할 수 있는 것: 1개의 문자 또는 1개의 숫자

예) ONE      DB      ?

FOUR     DB      ?, ?, ?, ?

MANY    DB      200 DUP(?)

★ 문자의 정의

STAR    DB       "*"

BIRD    DB      "R", "o", "b", "i", "n"

BIRD    DB      "Robin"

SQUOTE  DB    "Don't forget to"

DQUOTE  DB   'say "hello" to The Little Nipper for me.'

MSG      DB    "Hello, how are you?", 0DH, 0AH

★ 아래의 세 문장은 동일한 정의를 한다.

MESSAGE DB      "Hello, how are you?", 0DH, 0AH, "$"

MESSAGE DB      "Hello, how are you?", 0DH, 0AH, 24H

MESSAGE DB      "Hello, how are you?", 0DH, 0AH, 36

DB 지시어를 사용한 숫자의 정의

★ 1 바이트를 저장될 수 있는 숫자의 범위

숫자의 형(type)	가능한 범위
부호 없는 수 부호 있는 수	0∼255 -128∼127

예) 부호 없는 수로 초기화된 상수

URIGHT  DB      0, 34, 0FFH, 47, 1001101B

예) 부호 있는 수로 초기화된 상수

SRIGHT  DB      0, -34, 127, -128, -80H, -100010B

예) 에러가 있는 정의

UWRONG  DB      256, 123H, 101010101010B

WRONG   DB      -3333, 999, -0FFFH, -111110000011111B

DW 지시어를 사용한 문자의 정의

★ 워드 단위로 구성된 자료 항목을 정의한다.

- DW ∃ define words

- 1 워드에는 1개 또는 2개의 문자가 저장될 수 있고, 숫자나

오프셋이 저장될 수도 있다.

★  TWOCHAR 상수를 정의하고 □13□이라는 값으로 초기화하는 예

TWOCHAR DW      "13"

- 오른쪽 바이트 <= "1"이 저장됨 (31H)

- 왼쪽 바이트 <= "3"이 저장됨 (33H)

★ 워드에 한 문자만을 지정하면 어셈블러는 오른쪽 바이트에 00H를

저장하고 왼쪽 바이트에 그 문자에 해당하는 ASCII 코드를 저장한다.

예) ONECHAR DW      "1"

상수인 ONECHAR에 3100H를 저장한다.

★ DB 지시어와는 달리 문자열로 구성된 상수를 정의하는 데는 DW를

사용할 수 없다.

맞는 예) BCHARS  DB      "12345"

틀린 예) WCHARS  DW      "12345"

DW 지시어를 사용한 숫자의 정의

★ 각 워드도 부호 없는 정수와 부호 있는 정수를 저장할 수 있다.

숫자의 형	가능함 범위
부호 없는 수 부호 있는 수	0∼65535 -32768∼32767

예) 부호 없는 수로 초기화된 상수

URIGHT  DW      0, 34999, 0FFAEH, 47, 101101001101B

예) 부호 있는 수로 초기화된 상수

SRIGHT DW  0, -31999, -800H, 32767, -128, -100010001000B

틀린 예)

UWRONG DW  65536, 0FFFABH, 101010101010101010101010

SWRONG DW -876543, 99999, -0FFFFFH, -1111100000111110000B

DW 지시어를 사용한 오프셋의 정의

★  한 워드는 오프셋을 1개 저장할 수 있는 크기(16비트)이다.

예) 자료항목의 오프셋을 워드에 저장하는 예

LIST      DB      100 DUP(?)

LOFFSET DW      LIST

예) 프로시저의 이름을 워드에 지정하는 예

DISPLAY가 프로시저의 이름이라면, 다음과 같이 쓸 수 있다.

OFFSET  DW      DISPLAY

DD 지시어를 사용한 문자의 정의

★ DD 지시어는 더블워드 단위로 구성된 자료 항목을 정의한다.

★ 더블워드에 저장할 수 있는 것은 1개 또는 2개의 문자이거나, 숫자,

또는 완전한 주소(세그먼트 주소와 오프셋)이다.

★ 1개 또는 2개의 글자를 저장할 수 있는 더블워드 상수의 정의

(문자들은 더블워드의 앞 부분에 저장됨, 남은 바이트는 0으로 채워짐)

예)   ONECHAR DD      "A"

저장되는 값 = 41000000H

예)  TWOCHAR DD      "AB"

저장되는 값 = 41420000H

★  더블워드를 사용하여 두 문자 이상을 정의할 수는 없다.

틀린 예)    BADCHAR DD      "ABC"

DD 지시어를 사용한 숫자의 정의

	표 8-5			더블워드에 저장될 수 있는 수의 범위

숫자의 형	가능한 범위
부호 있는 수 실수	-2147483648∼2147483647 음수, 양수 : 10-38∼1038

예) 부호 있는 수로 초기화된 상수

SRIGHT DD 0, 83, 123456789, 0F5BCDH, 11110000111100001111B

예) 실수로 초기화된 상수

FRIGHT DD 0, 2.178, -3.141592, 3.123E10, 56.1E-12, 1E-10

틀린 예)

SWRONG  DD      12345678901, -999999999999

FWRONG  DD      1.23E100, 1E-100

DD 지시어를 사용한 주소의 정의

★ 더블워드는 완전한 주소 1개를 저장할 수 있는 공간(32비트)이다.

세그먼트 주소와 오프셋

★ 자료항목의 주소를 저장

LIST    DB      100 DUP (?)

LADDR   DD      LIST

★ 프로시저의 주소를 저장

DADDR   DD      DISPLAY

★ 어셈블러는 오프셋을 더블워드의 왼쪽 2바이트에 저장하고 세그먼트

주소를 남아 있는 오른쪽 반에 저장한다.

★ 코프로세서를 사용하지 않는 한, 더블워드는 완전한 주소를 저장

하는데 이외에는 사용하지 않는다.

DQ 지시어의 사용

★ 쿼드워드 단위로 구성된 자료 항목을 정의한다.

★ 쿼드워드가 저장할 수 있는 것은 1개 또는 2개의 문자이거나

1개의 숫자이다.

★ 실제로 쿼드워드는 수학 코프로세서가 사용할 숫자를 저장하는

데에만 사용한다. 코프로세서를 쓰지 않는 경우에는 쿼드워드가

필요하지 않다.

★ 쿼드워드에는 부호 있는 수나 실수를 저장할 수 있다.

	표 8-6			쿼드워드에 저장된 숫자의 범위

숫자의 형	가능한 범위
부호 있는 수 실수	-922337203685477808∼922337203685477807 양수, 음수 : 10-308∼10308

DT 지시어의 사용

★ 10바이트 그룹(TBYTES) 단위로 구성된 자료 항목을 정의한다.

DT <=> define ten bytes

★ 10바이트 그룹에 저장할 수 있는 것은 1개 또는 2개의 문자이거나 한 개의 숫자이다.

★ 일반적으로 수학 코프로세서가 사용할 숫자를 저장할 자료 항목을 정의하는 데 사용된다. 컴퓨터에 코프로세서가 없다면 이 지시어를   사용할 필요가 없다.

★ 저장할 수 있는 숫자의 종류는 실수와 압축 10진수(packed decimal)

- 압축 10진수(packed decimal number)

1바이트에 10진수 2자리를 저장한다.

첫째 바이트: 숫자의 부호(+ 또는 -)의 저장

남은 9바이트: 숫자를 저장하는데 사용

	표 8-7			10 바이트 그룹에 저장될 수 있는 수의 범위

숫자의 형	가능한 범위
실수 압축 10진수	양수, 음수 : 10-4932 ∼104932 -999999999999999999∼999999999999999999

이름 없는 항목의 주소 지정

★  TABLE   DB      1, 2, 3, 4, 5

DB      ?, ?

DB      8, 9, 10

★ 인덱스 레지스터를 사용한 자료 참조

TABLE[SI]         <- SI: 0, 1, 2, ... , 9

속성

★  속성(attribute)은 자료 항목의 특징을 설명한다.

자료 항목 -  5개의 속성을 가진다.

레이블    - 3개의 속성을 가진다.

★ 각 속성은 한 자료 항목의 한 가지 특성을 설명한다.

(1) TYPE 속성: 자료 항목을 구성하는 각 빌딩 블록의 바이트 수

예) 빌딩 블록: 바이트 => TYPE = 1, 워드 => TYPE = 2

쿼드워드 => TYPE = 4, 등

(2) LENGTH 속성: 자료 항목을 구성하는 빌딩 블록의 개수이다.

예) 200개의 워드로 구성된 변수는 길이(length)가 200이고,

50바이트로 구성된 상수는 그 길이가 50이다.

(3) SIZE 속성: 자료 항목에 예약된 전체 바이트 수이다.

예)  200워드로 구성된 변수의 SIZE는 400(바이트)이고,

50바이트로 구성된 상수의 SIZE는 50(바이트)이다.

(4) SEG 속성: 자료 항목이 속해 있는 세그먼트의 시작 주소이다.

(5) OFFSET 속성: 자료 항목의 첫째 바이트의 주소이다.

예)   TEMP    DW      200 DUP(?)

ZEROS   DB      50 DUP(0)

VALUE   DQ      ?

- TEMP의 TYPE은 2이고, LENGTH는 200이고, SIZE는 400이다.

- ZEROS의 TYPE은 1이고, LENGTH는 50이며 SIZE는 50이다.

- VALUE의 TYPE은 8이고, LENGTH는 1이며, SIZE는 8이다.

속성을 사용하는 연산자:

TYPE, LENGTH, SIZE, SEG,  OFFSET

★ 연산자(operator) - 오퍼랜드의 값을 결정하기 위하여 어셈블할 때

사용되는 기호(symbol)이다.

★ 자료 항목의 속성을 참조하는데 사용되는 연산자는 5개 있다.

TYPE   LENGTH   SIZE   SEG   OFFSET

(어셈블러는 이 수식의 값을 계산하여 기계어 명령을 생성할 때에

그 값으로 대치시킨다.)

예)    LIST    DW      100 DUP(?)

MOV     AX, TYPE LIST

=> MOV     AX, 2   ; 생성된 기계어 명령

MOV     AX, LENGTH  LIST

=> MOV     AX, 100  ; 생성된 기계어 명령

MOV     AX, SIZE LIST

=>  MOV     AX, 200

예) LIST의 세그먼트 주소를 AX 레지스터에 복사하려면

MOV     AX, SEG LIST

예) LIST의 오프셋을 복사하려면

MOV     AX, OFFSET LIST

틀린 예) MOV     AH, OFFSET LIST

산술 연산을 하는 연산자: +, -, *, /, MOD

★ 오퍼랜드 수식 안에서 간단한 산술 연산을 할 수 있도록 해주는

여러 가지 연산자가 있다.

	표 8-9			산술 연산자

연산자	의미
+ - * / MOD	덧셈 뺄셈 곱셈 나눗셈 모듈로(modulo)

예)  MOV     AX, TABLE+10

TABLE   DB      2*1024 DUP(?)

COUNT   DB      97/10

★ 산술 연산자는 어셈블러가 프로그램을 변환하는 과정에서 수행할

계산을 지정하는 데에 사용되는 것일 뿐, 프로그램이 실행될 때

산술 연산을 하는 것이 아니다.

★ 산술 연산자를 사용하면 프로그램이 훨씬 이해하기 쉽게 된다.

예)  12K바이트로 구성된 BUFFER 변수를 정의해보자.

(1)  12K =  12,288이므로, 다음과 같이 쓸 수 있다.

BUFFER  DB      12288 DUP (?)

(2) 아래와 같이 쓰면, 정의 자체에 그 의미가 나타나 있다.

BUFFER  DB      12*1024 DUP(?)

★  산술 연산자는 속성 연산자와 함께 사용될 수 있다.

LIST    DB      56  DUP(?)

BIGLIST DB      2 * (SIZE LIST) DUP (?)

PTR(pointer) 연산자

★ 프로그램에서 자료 항목을 참조할 때마다 어셈블러는 프로그램이

하고자 하는 일과 자료의 형이 일치하는가를 검사해 준다.

예)     MOV     AH, VALUE

=> VALUE 역시 8비트 길이여야 한다.

그렇지 않으면, 아래의 에러 메시지를 받음

Operand types must match

Illegal size for item

★ 아래의 정의를 보자.

TOTAL   DW      ?

(1) 보통의 경우에는 프로그램에서 TOTAL을 워드로 취급한다.

예)         MOV     AX, TOTAL

(2) TOTAL의 두 바이트를 따로따로 사용하고 싶을 때는?

- PTR(pointer) 연산자를 사용하여 어셈블러에게 이 명령에

한해서는 자료형을 무시하라고 일러줄 수 있다.

	표 8-10			PTR 연산자와 함께 사용될 수 있는 자료형

자료형	의미
BYTE WORD DWORD QWORD TBYTE	바이트 워드 더블워드 쿼드워드 10바이트로 된 그룹

예)      MOV      BH, BYTE PTR TOTAL

MOV     CH, BYTE PTR TOTAL+1

예)      PAIR    DB      ?, ?

-- PAIR의 두 바이트를 AX 레지스터에 복사하려면?

(1)    MOV     AX, PAIR  ; 틀린 예

(2)    MOV     AX, WORD PTR PAIR

예)

X       DB      "AB"

Y       DW      "AB"

==> X <= 4142H,     Y <= 4241H

레이블 지시어

★ 레이블(LABEL) 지시어를 사용하면 특정 속성을 갖는 이름을 정의할

수 있다.

(형식)   name	LABEL	type

(예)    BNAME   LABEL   BYTE

WNAME   DW      100 DUP(?)

=> LABEL 지시어는 기계어 프로그램에서 자리 차지를 전혀하지

않으므로, BNAME과 WNAME은 동일한 오프셋을 갖는다.

(1)  MOV     AX, WNAME+2

(2)  MOV     AH, WNAME+2  ; 틀린 예

(3)  MOV     AH, BNAME+2

<=>  MOV     AH, BYTE PTR WNAME+2

★ 형의 종류: BYTE, WORD, DWORD, QWORD나 TBYPTE

★ 코드 세그먼트 안에서 레이블을 정의할 때도 LABEL 지시어를 사용

할 수 있다. 이 레이블을 사용하여 한 명령에서 다른 명령으로 점프

하여 갈 수도 있다.

EQU(Equate) 지시어

★ Equate(EQU) 지시어는 프로그램이 어셈블되는 동안에 특정 값을 대신하는 심볼들을 정의하는 데 사용된다.

(형식)   name    EQU     expression

(예)     K       EQU     1024

ITEM1   DB      1024 DUP(?)

ITEM2   DB      2*1024 DUP(?)

ITEM3   DB      3*1024 DUP(?)

심볼 K를 위에서처럼 정의하였다면, 위의 세 문장은?

ITEM1   DB      K  DUP(?)

ITEM2   DB      2*K DUP(?)

ITEM3   DB      3*K DUP(?)

★ equate는 실제 기계어 프로그램에 남아 있을 어떤 것도 생성하지 않는다는 것을 이해하여야 한다. equate는 단지 어셈블 하는 동안에 어셈블러가 사용할 수 있는 약어(abbreviation)를 제공하는 역할을 할 뿐이다.

예) LSIZE를 100으로 세트하는 equate를 살펴보자.

LSIZE   EQU     100

프로그램 안에는 이 값에 의존하는 문장들이 많이 있을 수 있다.

WNAME   DB      LSIZE DUP(?)

WLIST    DW      LSIZE DUP(?)

MOV     AX, LSIZE

MOV     BX, LSIZE

그 후에 LSIZE를 200으로 바꾸기로 결정하였다고 하자.

이때 할 일: equate만 변경하고 다시 어셈블하면 됨.

Equate의 사용 규칙

(형식)   name    EQU     expression

(규칙)

- 이름(name)은 표준 규칙에 어긋나지 않는 이름

-  수식(expression):  0 -  65535 부호 없는 수 중의 1개

산술 연산자, 속성 연산자를 쓸 수 있다.

숫자는 10진법, 16진법, 2진법 모두 가능

(예)     MAX_VAL EQU     157

K        EQU     1024

TEN_K   EQU     10*K

ITS      EQU     1000011110100110B

HEXVAL EQU     0AF3H

LTYPE   EQU     TYPE LIST

(예)     MESSAGE EQU     "Hello, how are you?"

OUTPUT  DB      MESSAGE

★ equate의 프로그램에서의 위치?

- 어느 곳에 위치시켜도 된다. 가장 좋은 방법은 프로그램에 있는  equate를 모두 모아서 프로그램의 앞부분에 두는 것이다. 이렇게 하면 프로그램이 더욱 읽기 쉽게 된다.

위치 카운터: $ 심볼과 ORG 지시어

★ 어셈블러는 □위치 카운터(location counter)□라고 불리는 값을 유지하고 관리하는데, 이는 사용 가능한 다음 장소의 오프셋이다.

★ 어셈블러가 프로그램의 처리를 시작하면

-  위치 카운터는 0으로 세트된다.

- 어셈블러가 데이터나 명령문에 메모리의 공간을 확보할 때마다  위치 카운터의 값이 증가된다.

예)  현재 위치 카운터는 0H라고 하자. 어셈블러가 아래 지시어를

만나면        DB      32 DUP("STACK--")  는

100H(256 = 32×8)바이트 분량의 메모리를 확보한다.

위치 카운터는 이제 100H가 된다.

★ 프로그램 안에서 위치 카운터의 값을 참조할 수 있는데 이때 $를 사용한다.

예)    CURRENT EQU     $

> 어셈블러는 CURRENT를 이 equate가 처리될 때의 위치

카운터의 값으로 정의한다.

예) 문자열의 길이를 정의하는 간단한 방법

MSG     DB      "Hello"

L_MSG   EQU     $-MSG

★ 위치 카운터를 특정 값으로 세트할 수도 있는데 이때 사용되는 명령이 ORG(origin) 지시어이다.

(형식)         ORG     value

- 이 지시어를 일반적으로 사용하는 경우는 단 한 경우뿐이다. 어셈블러에게 오프셋이 0보다 큰 곳에서부터 어셈블을 시작하라고 지시할 때이다. 이는 COM 파일을 사용할 때 매우 유용하다.

ORG     100H

=> 어셈블러에게 오프셋이 100H인 곳에서부터 어셈블을 시작

하라고 지시한다. 그 결과로, 이 지시어는 프로그램의

앞부분에 100H (256) 바이트 분의 빈 공간을 남긴다.

Equate를 사용하는 예제

; set title and instruction set

TITLE   EQUATES -- sample program that uses equates

.286

;----------------------------------- STACK segment

SSEG    SEGMENT STACK

DB      32 DUP("STACK---")

SSEG    ENDS

;------------------------------------ EQUATES

CR      EQU     0DH     ; ASCII code for "carriage return"

LF      EQU     0AH     ; ASCII code for "line feed"

DISPLAY EQU     0001H   ; file handle for the display

;------------------------------------ DATA segment

DESG    SEGMENT

MSG     DB      "This is a message.",CR,LF

L_MSG   EQU     $-MSG

DSEG    ENDS

;------------------------------------ CODE segment

CSEG    SEGMENT 'CODE'

ASSUME  CS:CSEG, SS:SSEG, DS:DSEG

PAGE

MAIN    PROC    FAR

PUSH    DS

PUSH    0

MOV     AX,DSEG

MOV     DS,AX

; display the message

MOV     BX,DISPLAY

MOV     CX,L_MSG

LEA     DX,MSG

MOV     AH,40H

INT     21H

RET

MAIN    ENDP

CSEG    ENDS

END     MAIN