주소지정방식

Algorithm 2008. 8. 19. 09:30

C H A P T E R 4   ::: 주소 지정 방식 :::




공부할 내용
★ 주소 지정 방식 (addressing)
★ 세그먼트와 세그먼트 레지스터
★ 스택의 구현
★ 직접 주소 지정
★ 간접 주소 지정
★ 인덱싱
★ 인덱스 레지스터, 베이스 레지스터
★ 주소를 지정하는 일반적인 규칙
★ 코드세그먼트내에서의 주소 지정

기초적인 PC 주소 지정 방식
★ 기계어 명령이 사용하는 주소의 길이 = 16비트
   - 16비트를 사용하여 만들 수 있는 주소 = 0000H부터 FFFFH까지
      따라서, 메모리의 크기 <= 64K 바이트   (이는 지나친 제약임)
★ 더 나은 방법은?
   움직이는 팔을 가진 로보트가 있다고 하자.
   그 로보트의 팔은 64인치만큼 들락날락하며 움직일 수 있다고 하자.
   (1) 로보트가 방안의 어떤 곳에 고정되어 있는 경우
       그 팔은 64인치 이내의 거리에 있는 물건만을 잡을 수 있다.
   (2) 로보트가 방안을 돌아다닐 수 있다면 그 팔로 방안의
       어느 곳에 있는 물건도 잡을 수 있다.
  ★ 인텔 프로세서는 이런 방식으로 주소를 지정함.
인텔 프로세서의 주소 지정 방식
★ 어셈블리 언어 프로그램에 사용되는 주소
   = 세그먼트 주소 (segment address) + 오프셋(offset)
★ 세그먼트 주소 = 20 비트 크기  =>
   방안에서의 로보트의 위치에 해당
  오프셋 = 16비트 크기 => 로보트 팔에 해당
★ 실효 주소(effective address) : 바이트의 실제 주소
      = 세그먼트 주소 + 오프셋
   예) 세그먼트 주소가 50000H이고 오프셋이 62A3H라고 하자.
       실효 주소 = 50000H + 62A3H
                 = 562A3H
   예) 세그먼트 주소를 50000H로 고정한 상태에서 오프셋만을 변경
        시켜가면서 접근할 수 있는 바이트들은?
           실효주소의 범위 = 50000H ~ 5FFFFH (64K바이트 분량)
   예) 세그먼트 주소가 50000H일 때, 실효주소 8726BH번지의 자료를
        엑세스할 수 있나? no
        해결책: 8726BH가 64K바이트 이내에 들어오도록 세그먼트
               주소를 변경시켜야만 한다.

★ 하드웨어는 실효 주소를 계산하여 항상 20비트짜리 숫자로 만든다.
  즉, 실효 주소는 00000H ~ FFFFFH까지 될 수 있고,
  이제 1 메가바이트 크기의 메모리를 가질 수 있다.



세그먼트와 세그먼트 레지스터
★ 모든 프로그램은 세그먼트(segment) 단위로 나뉘어져야 한다.
   즉, 큰 프로그램을 작성할 때는 프로그램을 적당한 크기로
   나누어서 각 조각이 한 세그먼트에 들어갈 수 있도록 해야 한다. 
★  한 세그먼트의 최대 크기는 64K바이트이다.
★ 프로그램안에는 각 세그먼트의 시작 주소와 끝 주소를 어셈블러에게
  알려주는 특정 명령들이 있다.
★ 프로그램이 실행되는 동안에 프로세서는 각 세그먼트의
  세그먼트 주소를 CS, DS, ES 또는 SS라고 불리는 세그먼트 레지스터 
   (segment register)에 저장하여 두고 관리한다.

★ 한 프로그램이 가질 수 있는 세그먼트의 개수는 4개 이상일 수 있지
만 동시에 활성화될 수 있는 세그먼트의 개수는 4개뿐이다. 
  (이유: 프로세서에 들어있는 세그먼트 레지스터의 개수 = 4)
★ 4개의 표준 세그먼트
   (1) 코드 세그먼트(code segment)
       - 기계어 명령이 있는 곳
   (2) 데이터 세그먼트(data segment)
       - 자료가 저장되어 있는 곳
   (3) 엑스트라 세그먼트(extra segment)
       - 자료가 저장되는 곳 (필요시에 이 세그먼트를 둘 수 있음)
   (4) 스택 세그먼트(stack segment)
      - 스택이 있는 공간
★ 각 세그먼트의 주소가 저장되어 있는 레지스터
   CS: 코드 세그먼트의 주소
   DS: 데이터 세그먼트의 주소
   ES: 엑스트라 세그먼트의 주소
   SS: 스택 세그먼트의 주소
★ 모든 프로그램마다 4개의 표준 세그먼트가 있는가?
   아니다.
   - 모든 프로그램에는 최소한 (명령이 있을 곳인) 코드 세그먼트와
     스택 세그먼트가 있어야 한다.  (COM파일에는 스택이 없음)
   - 데이터 세그먼트와 엑스트라 세그먼트는 꼭 있을 필요는
     없으나 대부분의 프로그램에는 적어도 한 개의 데이터
     세그먼트가 있다.
세그먼트 레지스터의 용도
★프로그램에서의 주소 표시법
  [세그먼트 레지스터 이름] : [오프셋]

  예) 데이터 세그먼트의 시작점으로부터  6AH 바이트 떨어져 있는
      곳의 자료의 주소는?
        DS:6AH
   예) 엑스트라 세그먼트의 시작점으로부터 1A5H 떨어져 있는 곳의
       자료의 주소는?
       ES:1A5H

★ 프로그램이 실행될 때 프로세서는 오프셋을 해당 세그먼트 레지스터
의 값에 더하여 실효 주소를 얻는다.
   즉, 주속 DS:6AH라면, 프로세서는 6AH를 DS의 값에 더한다.
★ 각 세그먼트 레지스터에는 어떻게 해당 세그먼트의 시작주소가 저장
되는가?
   - 프로그램이 실행되기 전에 운영체제가 프로그램을 기억장치에
     로드(load)한다. 이 때에 프로그램의 각 세그먼트의 주소가 결정됨
   - CS, SS:운영체제가 초기화함.
     ES, DS: 프로그리머 자신이 (프로그램안에서) 초기화해야 함.

세그먼트 레지스터가 갖는 값
★ 세그먼트 레지스터에는 세그먼트 주소가 들어 있다.
  그렇다면, 16비트 크기의 레지스터에 20비트 크기의 세그먼트 주소가
어떻게 저장되는 것일까?
  해결책: 주소의 20비트 중에서 레지스터에는 최상위 16비트만을 저장
          남은 4비트는 모두 0으로 간주함.
   예) 운영체제가 코드 세그먼트를 217A0H번지에,
       스택 세그먼트를 1F8A0H에 로드하였다고 하자.
       이 때: CS 레지스터가 갖는 값 =  217AH이고
              SS 레지스터가 갖는 값 = 1F8AH가 된다.
★  프로그램의 각 세그먼트는 0H로 끝나는 주소에 자동적으로 load됨.
   (즉, 세그먼트는 항상 패러그래프 경계에 정돈된다.)
스택의 구현
★ SS(stack segment) 레지스터: 스택 세그먼트의 주소가 저장됨
     - 프로그램이 로드될 때 운영체제가 이 값을 설정해 준다.
★ SP(stack pointer) 레지스터: 스택의 탑의 오프셋이 저장됨
★ 스택 탑의 실효주소 = SS:SP
★ 스택에 저장되는 항목(entry)의 크기 = 16비트 (2바이트) 
★ SS 레지스터: 스택 영역의 가장 낮은 주소를 가리킨다.
   SP 레지스터의 초기값: 스택의 크기
   - 첫째 푸쉬 명령은 자료를 스택영역의 최상위 주소에 저장함
   - 그 다음 푸쉬 명령이 저장하는 자료는 그 다음 최상위 주소의
     엔트리에 저장된다.
   - SP 레지스터: 항상 자료가 마지막으로 저장된 곳을 가리킨다.
     (즉, 스택의 탑을 가리킨다.)
★ 스택은 최상위 주소로부터 시작하여 스택의 베이스를 향하여 아래
방향으로 자란다.
★ 일반적으로 한 항목이 푸쉬될 때는 아래와 같은 일이 이루어진다.
  1. SP는 다음의 빈 공간을 가리키기 위하여 그 값이 2 만큼 감소한다.
     (각 항목이 차지하는 공간은 2 바이트임을 잊지 말자.)
  2. 푸쉬할 항목이 SP가 가리키는 곳에 복사된다.
★ 자료가 팝될 때는 아래와 같은 일이 이루어진다.
  1. SP가 가리키는 곳의 항목이 적당한 다른 곳에 복사된다.
  2. 팝된 후에 스택의 탑에 있는 항목을 가리키기 위하여 SP는 그 값
     이 2만큼 증가된다.
★프로그램이 로드될 때, SP 레지스터는 첫째 항목이 저장될 장소보다
두 바이트 위에 있는 주소로 초기화된다. 첫째 푸쉬 명령은 SP를 2
감소시켜서 첫째 항목이 저장될 곳의 오프셋을 얻는다.


직접 주소 지정 방식
(1) 데이터 세그먼트안의 오프셋이 10AH인 곳을 지칭하려고 할 때
      DS:10AH
(2) 숫자대신 이름을 오프셋으로 사용 (고급언어의 변수에 해당)
   예) SUM이라는 이름이 데이터 세그먼트의 오프셋이 10AH인 곳을
      나타낸다고 하자.  이 곳을 참조할 때는
        DS:SUM
(3) 메모리 영역을 참조할 때, 그 주소가 데이터 세그먼트에 있으면
    세그먼트 레지스터의 이름을 생략할 수 있다.
       SUM
(4) 데이터가 다른 세그먼트에 있는 경우 (예. ES)
       ES:SUM
간접 주소 지정 방식
★ 오프셋이 레지스터에 저장되어 있는 경우
  예)  SI 레지스터의 값이 1000H라고 하자.
       MOV AX, SI  (1000H를 AX에 복사)
       MOV AX, [SI]  (오프셋 1000H에 저장된 자료를 AX에 복사)
★ 간접 주소 지정 방식에 사용될 수 있는 레지스터
   = SP, BP, BX, SI와 DI 임
★ 간접 주소 지정할 때, 대부분의 경우에 세그먼트 레지스터를 명시할
필요는 없다.
   (이유: 프로세서가 적당한 것을 이미 가정하고 있기 때문이다.)


  
   예) 데이터 세그먼트 내의 어떤 자료의 오프셋이 BX에 들어
       있다고 하자. 이 자료는 참조할 때는 다음과 같이 한다.
       [BX]
   예) BX의 값이 엑스트라 세그먼트 자료의 오프셋인 경우 
       ES:[BX]
[예외] 이 규칙을 따르지 않는 중요한 예외가 하나 있다.
      스트링을 MOV 하는 명령을 사용할 때, 프로세서는 DI 레지스터
      의 값이 엑스트라 세그먼트에 있는 오프셋임을 가정한다.


인덱싱(indexing)
★ 인덱싱: 1차원 배열 또는 2차원 배열과 같은 자료를 나타내는데 사용
★ 즉, 배열 전체에 이름을 1개 주고 배열 내의 각 항목(item)은
   첫째 자료 항목으로부터의 상대거리를 사용하여 참조함.
★ 베이스 주소(base address): 배열의 첫째 항목의 주소
예)  100개의 원소를 갖는 배열이 데이터 세그먼트에 있고, 그 원소들은
     연속된 100개의 바이트에 저장되어 있다고 하자. 각 원소는 한
     바이트를 차지한다. 배열의 이름은 LIST라고 하자.
     (1) 첫째 바이트를 엑세스할 때: LIST
     (2) 두번째 바이트를 엑세스할 때: LIST+1
★ 베이스 주소에 더해지는 수를 변위량(displacement)이라 함.
예) 100개의 워드로 구성된 배열 BIGLIST를 생각하여 보자. 각 워드가
    2바이트를 차지하므로 원소들의 변위량은 다음과 같이 된다.
    첫째 원소    ← BIGLIST
    둘째 원소    ← BIGLIST+2
    셋째 원소    ← BIGLIST+4
        
    100번째 원소   ← BIGLIST+198


인덱스 레지스터
★ 배열의 원소를 엑세스할 때 사용되는 변위량을 레지스터에 저장하여
두고 사용할 수 있음. 이 때 사용되는 레지스터를 인덱스 레지스터  
(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
★ 배열의 원소가 더블워드인 경우의 인덱스는 4의 배수이어야 하고,
  쿼드워드인 경우는 8의 배수이어야 한다. 어셈블리 언어를 사용할
  때는 프로그래머가 이를 직접 처리하여야 한다
   (고급언어에서와는 달리).
베이스 레지스터: BX 레지스터
★ 베이스 주소 역시 레지스터에 저장될 수 있다. 데이터 세그먼트에서
는  BX가, 스택에서는 BP가 이런 용도로 사용된다. 이 레지스터들은
  베이스 레지스터(base register)라고 불린다.
예) 배열 LIST는 다음과 같이 인덱스될 수 있다: LIST[DI]
    LIST의 오프셋을 BX 레지스터에 넣어 두었다면
           LIST[DI] <==> [BX][DI]
★ 베이스 주소를 레지스터에 넣어 두면 1개의 명령문을 사용하여 여러
개의 자료 구조를 액세스할 수 있다.
★ 더 복잡한 형식: TABLE[BX][DI]
  두 레지스터의 값이 자료 항목의 오프셋에 더해진다.
  예) BX에 20 들어 있고, DI에 4가 들어 있다면
      TABLE[BX][DI] <==> TABLE + 24 이다.
★ 이중 인덱싱(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 레지스터에 저장하여 두면 나중에
       어떠한 정보가 스택에 푸쉬되어도 프로시저 A로부터 전달받은
       자료는 BP의 값을 베이스 주소로 하여 액세스할 수 있다.
예) 프로시저 A가 10개의 워드를 스택에 푸쉬하였다고 하자.
    - 프로시저 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]


★ 아래의 패턴을 추천함
   (1) 직접 주소의 표현: 이름[베이스][인덱스]+상수
       예) TABLE[BX][SI]+8
   (2) 간접 주소의 표현: [베이스][인덱스]+상수
       예) [BP][DI]+8


코드 세그먼트 내에서의 주소 지정 방식
★ 코드 세그먼트로의 주소 지정:
   프로세서가 CS 레지스터와 IP 레지스터를 사용해 자동 해결
★ CS: 코드 세그먼트의 세그먼트 주소가 있음
   IP:바로 다음에 수행될 명령의 오프셋이 있음
★명령을 실행할 때마다 IP 는 그 다음 명령을 가리키도록 수정됨.
★ 다음에 실행될 명령이 분기 명령, 프로시저 호출 등이면
   프로세서는 IP 레지스터의 값을 그에 맞게 바꾼다.
★ 코드 세그먼트로의 주소 지정은 자동적으로 이루어지므로
   대부분의 경우에 CS 레지스터와 IP 레지스터의 값은 잊고 지내면 됨

'Algorithm' 카테고리의 다른 글

선점,비선점 스케쥴링  (1) 2008.08.19
병행프로세스와 상호배제  (0) 2008.08.19
RISC 기본원리  (0) 2008.08.19
deadlock 4가지  (0) 2008.08.01
B-, B+ Tree  (0) 2008.08.01
Posted by 으랏차
,