본문 바로가기
시스템 프로그래밍

Assemblers (4)

by sepang 2021. 10. 15.

  저번 글에서 기계 독립적인 어셈블러의 특징 5개 중 4개를 다뤄봤다. 이제 Control Section이라는 한가지 특징이 남았는데 다른 특징들보다 내용이 많아서 이렇게 따로 다루게 됐다. 이전 특징들에 비해 생각할 부분들이 많을 것 같다. 그리고 뒤에서는 어셈블러의 Design Option에 대해서도 알아보자.

Control Section

  Control Section(CS, 제어 섹션)은 assembly 이후의 프로그램 일부인데, 각각이 정체성을 유지한다. 각 CS는 다른 섹션과 독립적으로 로드되거나 재배치 될 수 있다. 프로그램의 서브루틴이나 기타 논리적 하위 부문에 서로 다른 제어 섹션이 사용된다. 프로그래머는 각 CS를 개별적으로 조립, 로드 및 조작을 할 수 있다. 그 결과 발생하는 유연함은 제어 섹션의 주요 이점이다.

 

Program Linking

  CS는 프로그램의 논리적으로 관련된 부분을 형성할 때, 그것들을 연결할 수 있는 몇 가지 수단을 제공해야 한다. 때문에 한 CS의 instructions은 다른 섹션에 있는 instructions 및 데이터를 참조할 수 있어야 한다. 

  하지만 CS가 독립적으로 로드되고 재배치되기 때문에 어셈블러는 이러한 참조를 처리할 수 없다. CS간의 이러한 참조를 외부 참조(external reference)라고 한다. 어셈블러는 실행 시 다른 CS가 어디에 위치할지 모르기 때문에 로더가 필요한 링크를 수행할 수 있는 각 외부 참조에 대한 정보만 생성한다.

  이제 directives에 의해 어떻게 외부 참조가 처리되는지 설명할 것이다. 밑의 fig 1은 3개의 CS를 사용하는 예제 프로그램을 보여주고 있다. 하나는 메인 프로그램이고 다른 하나는 서브루틴 용이다.

  • CSECT: 새 CS의 시작을 알리는 어셈블리 directives
  • EXTDEF: 다른 섹션에서 사용하기 위해 현재 CS에 정의된 symbol에 대한 어셈블리 directives
    • 이러한 symbol을 외부 symbol라고 한다. CS 이름은 자동으로 외부 기호로 간주된다.
  • EXTREF: CS내부에서 사용되는 이름 기호에 대한 어셈블리 directives. 다른 곳에서 정의됨

  어셈블러는 프로그램 블록과 마찬가지로 각 CS에 대해 별도의 LOC을 설정한다. 쉽게 생각하자면 즉 내가 다른 섹션의 ABC라는 레이블의 값이 필요하다고 하면 ABC가 있는 섹션에서는 EXTDEF를 이용해 ABC를 외부에서 사용할 수 있게끔 알려야하고, ABC가 필요한 섹션에서는 EXTREF로 내가 다른 섹션에 있는 ABC를 여기서 사용하겠다라고 알려야한다.  fig 1을 보면 이해가 더 잘 될 것 같다.

fig 1

  CSECT를 이용하여 프로그램을 COPY, RDREC, WRREC 3개의 CS로 나눠진 것을 확인할 수 있다. 그리고 COPY 섹션에서는 EXTDEF를 이용해 BUFFER, BUFEND, LENGTH를 다른 섹션에서 참조할 수 있게 하고 또 EXTREF를 이용해 RDREC과 WRREC을 참조할 수 있다. 그리고 RDREC과 WRREC에서는 EXTREF를 이용해 COPY 섹션의 BUFFER, BUFEND, LENGTH등을 참조할 수 있다.

How to handle External References?

  이전까지의 프로그램과 fig 1의 차이에 대해 알아보자. 어셈블러는 외부 참조(ex. RDREC)을 포함하는 CS가 로드되는 위치를 알지 못하므로 참조를 위해 주소를 조립할 수 없다. 대신 어셈블러는 0이라는 주소를 삽입하고 로더에 정보를 전달하므로 이후 로드시 적절한 주소를 삽입할 수 있게된다.

  • Ex)   CLOOP    +JSUB    RDREC     4B100000
  • Ex)                +STCH    BUFFER,X     57900000

  이때는 format 4를 사용하여 실제 주소를 삽입할 공간을 제공해야 한다. memory 어디에 로드될지 모르니깐 메모리 전체를 표현할 수 있는 format 4 명령을 써야하기 때문에 이는 당연하다.

 

New Record Types

  어셈블러는 로더가 필요한 위치에 적절한 값을 삽입하도록 하는 정보를 object program에 포함해야한다. 때문에 새로운 record가 필요한 것이다.

  Define record는 EXTDEF에 의해 CS에 정의된 외부 symbol용이다. 해당 CS에 있는 각 외부 symbol의 상대 주소를 나타낸다.

  • Col. 1: D
  • Col. 2-7: 해당 CS에 정의된 외부 symbol의 이름
  • Col. 8-13: 해당 CS의 상대 주소(16진수)
  • Col. 14-73: 기타 외부 symbol에 대해  Col. 2-13의 정보 반복

  Refer record는 EXTREF에서 CS에 사용하는 외부 symbol용이다. 여기서는 사용가능한 주소 정보가 없다.

  • Col. 1: R
  • Col. 2-7: 해당 CS에서 언급한 외부 symbol의 이름
  • Col. 8-73: 기타 외부 참조 symbol 이름

  그리고 이전에 program relocation 때 나왔던 Modification record가 일부 변경된다.

  • Col. 1: M
  • Col. 2-7: 수정할 필드의 시작 주소(16진수)
  • Col. 8-9: 수정할 필드의 길이(단위: half-byte)(16진수)
  • Col. 10: 수정 플래그(+ or -)
  • Col. 11-16: 표시된 필드에 값을 추가하거나 뺀 외부 symbol

fig 2

  3개의 CS로 나눠져서 object code가 3개의 프로그램으로 분리된 것 처럼 보인다.

  우선 COPY 섹션의 define record를 확인해보자. BUFFER, BUFFEND, LENGTH와 각각의 상대주소를 확인할 수 있다. 그리고 각 섹션의 refer record에서는 해당 섹션에서 참조할 외부 기호의 이름들을 확인할 수 있다. 이렇게 해주면 이 프로그램이 3개의 섹션으로 나눠져도 로더가 필요한 외부 섹션의 정보가 메모리 어디에 위치하는지 알 수 있게된다.

  그럼 로더는 00000으로 바꿔놨던 address field 값들을 변경해줘야 한다. 이는 modification record를 보고 변경한다. COPY 섹션의 첫번째 modification record를 확인해보자. 프로그램의 4번째 byte는 '4B100000'에서 '4B'를 가리키고 4-bit*5 크기의 address field를 변경해야 하므로 '5'가 있음을 확인할 수 있다. '+RDREC'이라는 것은 해당 수정할 필드에서 RDREC의 주소만큼 더하라는 것이다.

  그러므로 로더는 모든 외부 기호에 대해 다음을 수행해야 하는 것이다.

  • 정의된 레코드에서 상대주소 찾기
  • 기호가 정의된 곳에 CS의 시작주소 추가
  • field 수정

 

Assembler Design Option

  우리는 계속해서 2-pass 어셈블러에 대해 다뤘다. 이것은 처음 pass에서는 기호 테이블을 생성하고 두번째 pass에서는 object code를 생성한다. 

  하지만 이것이 어셈블러를 설계하는 유일한 방법은 아닐 것이다. 어셈블러는 1-pass나 multi-pass 알고리즘으로도 설계할 수 있다. 여기서는 소스 코드를 한 번만 스캔하는 1-pass 어셈블러에 대해 다룬다. 이는 소스 프로그램에 대한 추가적인 pass의 오버헤드를 줄여주지만 스캔 도중에 생성된 object code를 patch해야하는 경우가 있다.

  이러한 1-pass 어셈블러에는 두 가지 타입이 있다. Type-1Load-and-Go Assembler다. 이 어셈블러는 object program이 작성되지 않아 로더의 필요 없고 즉각적인 실행을 위해 메모리에 object code를 직접 생성한다.  Type-2는 나중에 실행 가능하도록 일반적인 종류의 object program을 생성하여 로더를 필요로 한다.

  여기서 우리는 전방 참조(forward reference)에 대한 문제를 극복해야 한다. 2-pass 처럼 object code 작성 이전에 기호 테이블을 생성하지 않기 때문이다. 명령의 피연산자는 종종 소스 프로그램에서 아직 정의되지 않은 기호일 수 있다. 그러므로 어셈블러는 object code로 번역될 때 삽입할 주소를 알지 못한다.

  fig 3는 1-pass 어셈블러를 위한 예제 프로그램이다. 이 역시 SIC/XE에서 다뤘던 프로그램과 동일한 로직을 갖고 있다. 우선 전방 참조를 극복하기 위해 모든 데이터 항목 정의는 해당 항목을 참조하는 명령보다 먼저 배치된다. 하지만 명령의 레이블에 대한 전방 참조는 쉽게 제거될 수 없다. 이는 및 fig 3의 line 15, 30, 35, 65, 155를 확인해보면 그 이유를 쉽게 알 수 있을 것이다. 그렇다면 TYPE 1&2 어셈블러는 이 문제를 어떻게 해결할 수 있을까?

 

fig 3. sample program for a one-pass assembler

Type 1 One-Pass Assemblers: Load-and-Go

  해당 타입은 프로그램 개발 및 테스트를 지향하는 시스템에서 유용하다. 프로그램은 거의 실행될 때마다 re-assembled된다. Load-and-Go 어셈블러는 2차 저장소(ex. HDD, SSD)에 object code를 작성하지 않고 메모리에서 객체 코드를 생성한다. 이는 어셈블리 과정의 효율성을 높인다(메모리의 속도가 2차 저장소의 속도보다 훨씬 빠름).

  여기서는 전방 참조를 어떻게 해결할까? 바로 정의되지 않은 기호를 이 기호를 참조하는 필드 주소와 함께 SYMTAB에 저장하고 나중에 기호가 정의되면 SYMTAB를 찾아 올바른 주소로 필드를 수정함으로써 전방 참조 문제를 해결하는 것이다. 즉 한번의 pass에서 SYMTAB를 만들어가는 것이다.

fig 5-1
fig 5-2

  fig 5-1은 line 40까지 스캔했을 때의 object code와 SYMTAB를 나타낸 것이다. RDREC, WRREC, ENDFIL이 정의되기 전에 이를 참조하고 있다. 그래서 일단은 해당하는 주소값 부분은 비어있다. SYMTAB에서는 해당 기호를 참조하는 위치를 연결 리스트 형식으로 연결한다.

  fig 5-2는 line 160까지 스캔했을 때의 상황이다. RDREC와 ENDFIL이 선언되어 위에서 링크드 리스트에 들어있던 해당 기호의 참조 위치에 해당 기호의 주소를 넣어줘 비어있던 부분을 채워준다. 아직까지 WRREC은 선언되지 않았는데 한번더 참조가 발생하여 연결 리스트 뒤에 해당 참조 위치를 연결해준다. 그리고 EXIT도 선언 이전에 참조가 발생하여 위와 같은 과정을 거친다.

Type 2 One-Pass Assemblers

  해당 타입은 디스크에 object program을 쓴다. 전방 참조는 어떻게 해결할까? 전방 참조는 우선 이전과 같이 리스트에 입력된다. 이후 기호에 대한 정의가 발견되면 피연산자 주소가 정확한 다른 text record를 생성한다. 이후 로드되면 로더에 의해 올바른 주소가 삽입된다.

fig 6

    두번째 text record에는 line 10-40까지 생성된 object code가 포함되어 있다. line 45에서 ENDFIL의 정의가 발견되면 어셈블러는 세번째 text record를 생성한다. 이는 2024(ENDFIL 주소)를 201C(line 30의 JEQ의 피연산자 address field)위치에 로드하도록 지정하는 것이다. 어떻게 이러한 text record를 다른 text record와 구분할 수 있는걸까? 이렇게 수정을 요구하는 text record에는 이전에 이미 object code로 번역했던 address 영역이 있는데 이는 기존의 context와 당연히 다르다. 때문에 전방 참조를 위한 record임을 인식할 수 있는 것이다.


이미지 출처

  • “Computer Organization and Design (5th Edition)” by Patterson & Hennessy]

'시스템 프로그래밍' 카테고리의 다른 글

Operating Systems(OS) Overview  (0) 2021.11.05
Linkers and Loaders  (0) 2021.11.01
Assemblers (3)  (0) 2021.10.15
Assemblers (2)  (0) 2021.10.14
Assemblers (1)  (0) 2021.09.28

댓글