C H A P T E R

Chapter 2: 수의 체계

Chapter 2: 수의 체계

4
ㅔ

주소 지정 방식

공부할 내용

★ 주소 지정 방식 (addressing)

★ 세그먼트와 세그먼트 레지스터

★ 스택의 구현

★ 직접 주소 지정

★ 간접 주소 지정

★ 인덱싱

★ 인덱스 레지스터, 베이스 레지스터

★ 주소를 지정하는 일반적인 규칙

★ 코드 세그먼트 내에서의 주소 지정

주소 지정 방식 (인텔)

★ 기본적인 주소 지정 방식

- 기계어 명령이 사용하는 주소의 길이 = 16비트

- 16비트를 사용하여 만들 수 있는 주소

∀ 메모리의 크기 ≤ 64K 바이트

★ 어셈블리 언어 프로그램에 사용되는 주소

= segment address(20 bits) + offset(16 bits)

= 실효 주소(effective address): 바이트의 실제 주소

예) 세그먼트 주소를 50000H로 고정한 상태에서 오프셋만을 변경

시켜가면서 접근할 수 있는 바이트들은?

실효주소의 범위 = 50000H ∼ 5FFFFH (64K바이트 분량)

★ 하드웨어는 실효 주소를 계산하여 항상 20비트짜리 숫자로 만든다.

즉, 실효 주소는 00000H ∼ FFFFFH까지 될 수 있고, 1 MB 크기의 메모리를 가질 수 있다.

세그먼트와 세그먼트 레지스터

★ 모든 프로그램은 세그먼트(segment) 단위로 나뉘어져야 한다.

즉, 큰 프로그램을 작성할 때는 프로그램을 적당한 크기로 나누어서 각 조각이 한 세그먼트에 들어갈 수 있도록 해야 한다.

★ 한 세그먼트의 최대 크기는 64K바이트이다.

★ 프로그램이 실행되는 동안에 프로세서는 각 세그먼트의 주소를 세그먼트 레지스터(segment register)(CS, DS, ES, SS)에 저장하여 두고 관리한다.

★ 한 프로그램에서 동시에 활성화 될 수 있는 세그먼트의 개수는 4개이다. (∵ 프로세서에 들어있는 세그먼트 레지스터의 개수 = 4)

★ 4개의 표준 세그먼트

(1) Code Segment: 기계어 명령이 있는 곳

(2) Data Segment: 자료가 저장되는 곳

(3) Extra Segment: 자료가 저장되는 곳

(4) Stack Segment: 스택이 있는 공간

★ 각 세그먼트의 주소가 저장되어 있는 레지스터: CS, DS, ES, SS

★ 모든 프로그램에는 최소한 (명령이 있을 곳인) 코드 세그먼트와 스택 세그먼트가 있어야 한다.

cf.) COM파일에는 스택이 없음

세그먼트 레지스터의 용도

★ 프로그램 내에서의 주소 표시법

[세그먼트 레지스터 이름] : [오프셋]

★ 프로그램이 실행될 때 프로세서는 오프셋을 해당 세그먼트 레지스터의 값에 더하여 실효 주소를 얻는다.

즉, 주소가 DS:6AH라면, 프로세서는 6AH를 DS의 값에 더하여 실효주소를 얻음.

★ 각 세그먼트 레지스터에는 어떻게 해당 세그먼트의 시작주소가 저장되는가?

- 프로그램이 실행되기 전에 운영체제가 프로그램을 기억장치에 load한다. 이 때, 프로그램의 각 세그먼트 주소가 결정됨

- CS, SS : 운영체제가 초기화

DS, ES : 프로그램 안에서 초기화

세그먼트 레지스터에 저장되는 값

★ 세그먼트 레지스터에는 세그먼트 주소가 들어 있음.

그렇다면, 16비트 크기의 레지스터, 20비트 크기의 세그먼트 주소?

∀ 주소의 20비트 중에서 레지스터에는 최상위 16비트만을 저장.

예) 운영체제가 코드 세그먼트를 217A0H번지에 스택 세그먼트를 1F8A0H에 로드하였다고 하면,

∀ CS 레지스터가 갖는 값 = 217AH

∀ SS 레지스터가 갖는 값 = 1F8AH

스택의 구현

★ SS(stack segment) 레지스터 : 스택 세그먼트의 주소가 저장됨

- 프로그램이 로드될 때 운영체제가 이 값을 설정해 준다.

- 스택 영역의 가장 낮은 주소를 가리킨다.

★ SP(stack pointer) 레지스터 : 스택의 탑의 오프셋이 저장됨

- SP 레지스터의 초기 값 : 스택의 크기

- SP 레지스터: 항상 자료가 마지막으로 저장된 곳을 가리킨다.

★ 스택은 최상위 주소로부터 시작하여 스택의 베이스를 향하여 아래 방향으로 자란다.

★ push, pop에 따라 SP의 값이 변화함.

★ 스택 탑의 실효주소 = SS:SP

직접 주소 지정 방식

★ 데이터 세그먼트안의 오프셋이 10AH인 곳을 지칭하려고 할 때

∀ DS:10AH

★ 숫자대신 이름을 오프셋으로 사용

예) SUM이라는 이름이 데이터 세그먼트의 오프셋이 10AH인 곳을

나타낸다고 하면 ∀ DS:SUM

★ 메모리 영역을 참조할 때, 그 주소가 데이터 세그먼트에 있으면

세그먼트 레지스터의 이름을 생략할 수 있다. ∀ SUM

★ 데이터가 다른 세그먼트에 있는 경우 (예: ES) ∀ ES:SUM

간접 주소 지정 방식

★ 오프셋이 레지스터에 저장되어 있는 경우

예) SI 레지스터의 값이 1000H라고 하자.

MOV AX, SI (1000H를 AX에 복사)

MOV AX, [SI] (오프셋 1000H에 저장된 자료를 AX에 복사)

★ 간접 주소 지정 방식에 사용될 수 있는 레지스터

∀ SP, BP, BX, SI, DI

★ 간접 주소 지정할 때, 대부분의 경우에 세그먼트 레지스터를 명시할 필요는 없다. ∀ 다음 페이지

	표 4-2			간접 주소 지정 방식에서의 세그먼트 레지스터의 묵시적 용도

레지스터	묵시적 세그먼트 레지스터
[SP] [BP] [BX] [SI] [DI]	SS SS DS DS DS(스트링 명령의 경우에는 ES)

예) BX의 값이 엑스트라 세그먼트 자료의 오프셋인 경우 ∀ ES:[BX]

인덱싱(indexing)

★ 인덱싱 : 1차원 또는 2차원 배열과 같은 자료를 나타내는데 사용

★ 즉, 배열 전체에 이름을 1개 주고 배열 내의 각 항목(item)은 첫째 자료 항목으로부터의 상대거리를 사용하여 참조함.

★ 베이스 주소(base address): 배열의 첫째 항목의 주소

예) 100개의 원소를 갖는 배열이 데이터 세그먼트에 있고, 그 원소들은 연속된 100개의 바이트에 저장되어 있다고 하자. 각 원소는 한 바이트를 차지한다. 배열의 이름은 LIST라고 하자.

(1) 첫째 바이트를 엑세스할 때 : LIST

(2) 두 번째 바이트를 엑세스할 때 : LIST+1

★ 베이스 주소에 더해지는 수를 변위량(displacement)이라 함.

인덱스 레지스터

★ 배열의 원소를 엑세스할 때 사용되는 변위량을 레지스터에 저장하여 두고 사용할 수 있음. 이 때 사용되는 레지스터를 인덱스 레지스터   (index register)라고 한다.

★ 인덱스 레지스터로 사용될 수 있는 레지스터 : SI, DI

예) 100바이트로 구성된 배열 LIST를 가정. 프로그램이 이 배열의 원소를 처음부터 끝까지 순서대로 참조한다고 하자. 이 때 SI 레지스터의 값을 0부터 99까지 변화시키면서 LIST[SI]를 사용함.

∀ LIST[SI]의 의미 : SI에 들어 있는 값(value)을 LIST의 오프셋에 더하여 얻은 주소에 있는 자료를 참조하라.

예) 100개의 워드로 된 배열 BIGLIST에서 인덱스를 위해 DI 레지스터를 사용한다면,

- 원소를 엑세스할 때 : BIGLIST[DI]를 사용

- 첫째 원소를 참조하려면 DI = 0

둘째 원소를 참조하려면 DI = 2

셋째 원소를 참조하려면 DI = 4

……

n 번째 원소를 참조하려면 DI = (n-1) × 2

베이스 레지스터: BX 레지스터

★ 베이스 주소 역시 레지스터에 저장될 수 있다. 데이터 세그먼트에서는  BX가, 스택에서는 BP가 이런 용도로 사용된다.

예) 배열 LIST는 다음과 같이 인덱스 될 수 있다: LIST[DI]

LIST의 오프셋을 BX 레지스터에 넣어 두었다면

LIST[DI] ∃ [BX][DI]

★ 베이스 주소를 레지스터에 넣어 두면 1개의 명령문을 사용하여 여러 개의 자료 구조를 액세스할 수 있다.

★ TABLE[BX][DI]

두 레지스터의 값이 자료 항목의 오프셋에 더해진다.

★ 이중 인덱싱(double-indexing)을 사용하여 얻는 점

- 자료구조 안에서 베이스 주소를 설정할 수 있다는 것이다.

예) TABLE을 1바이트 원소로 30행 100열짜리 테이블이라고 하자.

→ BX : 특정 행을 가리키도록 하자.

→ DI나 SI : 그 행의 원소를 인덱스할 수 있다.

첫째 행: 0번째 바이트부터 99번째 바이트

둘째 행: 100번째 바이트로부터 199번째 바이트

18번째 행의 57번째 원소 ∀

BX = 1700, SI = 56를 저장한 후,

TABLE[BX][SI] (의미 : TABLE + 1756)

베이스 레지스터: BP 레지스터

★ 스택의 주소 지정 : 대부분의 경우에 SS, SP 레지스터 사용

SS : 세그먼트 주소,   SP : 스택 탑의 오프셋

★ 가끔은 스택 내부에 있는 정보를 액세스할 필요가 있을 때도 있다.

이 때는 BP 레지스터에 스택 내에서의 베이스 주소를 저장한다.

예) 프로시저 A가 프로시저 B를 호출할 때 스택을 통하여 어떤 정보를 프로시저 B에게 전달한다고 하자.

- 프로시저 B가 프로시저 A로부터 제어권을 넘겨받은 순간에 스택 탑의 오프셋을 BP 레지스터에 저장하여 두면 나중에 어떠한 정보가 스택에 push되어도 프로시저 A로부터 전달받은 자료는 BP의 값을 베이스 주소로 하여 액세스할 수 있다.

예) 프로시저 A가 10개의 워드를 스택에 push하였다고 하자.

- 프로시저 B의 실행이 시작되면, 프로시저 B가 가장 먼저 하는 일

은 SP의 값을 BP에 복사함으로써 스택 탑의 오프셋을 저장함.

- 프로시저 B는 언제라도 10개의 워드를 다음처럼 접근할 수 있음.

SS:BP

SS:BP+2

SS:BP+4

……

SS:BP+18

★ BP가 베이스 주소로 사용되면 SS가 묵시적으로 가정됨.

SS:BP+2 ∃ BP+2

주소를 지정하는 일반적인 규칙

★ 직접 주소를 지정할 때

TABLE, TABLE[SI], TABLE[DI]+8, TABLE[BX][SI]+8

★ 간접 주소를 지정할 때

- SP, BP, BX, SI 또는 DI를 사용한다.

- BP나 BX가 사용될 때는 SI나 DI가 인덱스로 사용된다.

예) [BP], [SI], [BX][DI], [SI]+4, [BP][DI]+4

★ 간접 방식이든 직접 방식이든 하나의 주소에는 2개 이상의 베이스 레지스터가 사용될 수도 없고 2개 이상의 인덱스 레지스터가 사용될 수도 없다.

★ 인덱스의 값을 지정할 때 어셈블러는 다음의 규칙을 따른다.

□ 인덱스의 값에는 특정 순서가 없다.

□ 레지스터의 이름은 대괄호에 싸여 있어야 한다.

□ 레지스터의 이름들과 한 개의 상수 변위량을 모두 하나의 대괄호 안에 넣어 사용할 수 있으며, 이 때 이들은 + 부호로 분리한다.

□ 레지스터의 이름 앞에 상수 변위량을 쓸 수도 있는데 이 때는 이 두 값 사이에 + 부호가 있을 필요가 없다.

예) TABLE[BX][SI]+8, TABLE[BX+SI+8], TABLE[8+SI+BX]

[BP][SI]+12, 12[BP][SI], 12[BP+SI]

코드 세그먼트 내에서의 주소 지정 방식

★ 코드 세그먼트에서의 주소 지정 :

프로세서가 CS 레지스터와 IP 레지스터를 사용해 자동 해결

★ CS : 코드 세그먼트의 세그먼트 주소가 있음

IP : 바로 다음에 수행될 명령의 오프셋이 있음

★ 명령을 실행할 때마다 IP 는 그 다음 명령을 가리키도록 수정됨.

★ 다음에 실행될 명령이 분기 명령, 프로시저 호출 등이면 프로세서는 IP 레지스터의 값을 그에 맞게 바꾼다.