TSG: MMIX 1.4.1 Subroutines (2)


지난주에 이어서 서브루틴 사용에 유용한 명령 3개에 대해 읽었다.

Assembly language features

1. PREFIX

프로그램이 큰 경우 레지스터 뿐 아니라 심볼명도 중복되는 일이 생길 수 있다. 그래서 일종의 네임스페이스를 지정해서 일정 범위 안의 심볼을 특정 prefix 범위 안으로 묶을 수 있다. 네임스페이를 지정하는데에는 콜론(:)을 사용한다.

  1. 콜론(:)으로 시작하지 않는 심볼은 모두 current prefix 가 앞에 붙은 것으로 간주한다.
  2. current prefix 의 기본값은 “:” 이다.
  3. PREFIX 명령으로 current prefix 를 갱신할 수 있다.
...                     # current prefix ":" (default)
ADD     x,y,z
PREFIX  Foo:            # current prefix "Foo:"
ADD     x,y,z
PREFIX  Bar:            # current prefix "Foo:Bar:"
ADD     :x,y,:z
PREFIX  :               # current prefix ":"
ADD     x,Foo:Bar:y,Foo:z
...

2. LOCAL

특정 expression 이 지역(local) 레지스터임을 보장하는 assertion 이다. 예를 들어,

LOCAL $40

이렇게 하면 \$40 은 전역 레지스터로 쓰일 수 없다.

3. BSPEC .. ESPEC

특정 데이터를 별다른 처리를 하지 않고 그냥 저장하는 섹션을 만든다. 프로그램이 알아서 사용할 바이너리 데이터로, 리소스나 메타정보 등을 저장한다. XML<![CDATA[ … ]]> 와 비슷한 느낌이다.

컴파일러나 링커 등이 Linkage 를 알아 내기 위해서도 사용한다고 한다.

BSPEC 42
TETRA 1,2,3
ESPEC

BSPEC 뒤에는 0 ~ 255 사이의 정수가 올 수 있다. GNU Binutils 에서 80 을 사용한다.

Strategic considerations

큰 라이브러리에 포함될 일반적인 서브루틴을 만드는 경우 단 하나라도 전역 레지스터를 사용하는 것은 큰 부담이 될 수 있다. 수백개 이상의 서브루틴이 각자 전역 레지스터를 하나씩 내놓으라고 하면 어쩌겠는가? 길고 복잡한 프로그램을 작성하는 전략(?)에 대하여 Knuth 님이 정리해 주셨다.

  1. Initial idea
  2. A rough sketch of the program
  3. First working program
  4. Reexamination
  5. Debugging

Silly

Gsong 님이 1.3.2 의 연습문제 5번,

What do you get from 'BYTE 3+"pills"+6' ?

에 대해 질문하셨다. 책 뒤에 답이 있긴 하지만 그 답이 나오는 지를 모르겠다는 것. 비밀은 책 어딘가세 설명되었던 BYTE 의 동작에 숨어있다. BYTE "abc"MMIXAL 에 의하여 BYTE 97,98,99 로 치환된다. 이 치환 작업이 BYTE 명령의 피연산자의 계산 이전에 일어난다. 마치 C Macro 처럼. pills 의 아스키 코드는 112, 105, 108, 108, 115 인데 이 치환 작업을 위의 코드에 넣으면 아래와 같이 변한다.

BYTE 3+"pills"+6
BYTE 3+112,105,108,108,115+6
BYTE 115,105,108,108,121

얻어진 아스키 코드 115,105, 108, 108, 121 를 텍스트로 나타내면,

>>> ''.join(map(chr, [115,105, 108, 108, 121]))
'silly'

silly 가 된다.

스터디 마무리는 이 사진으로:

jpg

Comments