어셈블리 언어로 작성된 프로그램을 기계어 코드(.o와 같은 object files)로 변환해주는 시스템 소프트웨어
LDA → 00 )용어 정리
- Assembly language? 기계가 이해하는 명령어의 기호적 표현 (사람이 읽기 쉬운 형태)
- Object file? 기계어 명령어 + 데이터 + 메모리 배치에 필요한 정보가 결합된 파일
- label? 명령어 또는 데이터가 위치한 메모리 주소에 붙인 이름
- Opcode Table? 어셈블리어의 연산 코드와 실제 기계어 코드를 매핑한 표
- Symbol Table? 프로그램에 사용된 레이블과 해당 메모리 주소를 연결한 표
functional statements 3가지
어셈블러에 의해 1개 이상의 object code 바이트로 번역됨
이 코드는 실행 시간에 실제 실행됨
각 명령어는 하나의 연산(기능)에 대응됨
어셈블러에게 특정 작업을 수행하라고 지시함
object code에는 영향을 주지 않음
예: WORD 지시어는 1-word 정수를 생성하는 데이터 정의어이다.
여러 문장을 축약해서 나타낸 것
어셈블러는 매크로를 그에 해당하는 문장들로 확장한 다음,
이 확장된 문장들을 어셈블함
READ MACRO &BUFFER
STA &BUFFER
...
MEND
READ MACRO &BUFFER:
READ 정의&BUFFER : 매크로 인자(parameter)STA &BUFFER:
MEND: 매크로 정의 끝
READ INDEV
...
INDEV BYTE X'F1'
→ INDEV에 0xF1을 저장해 두고, 그 후 A 값으로 덮어씀
READ INDEV:
INDEV는 그 매크로에 전달되는 인자STA INDEV를 의미하게 됨INDEV BYTE X'F1':
어셈블리 소스 프로그램을 오브젝트 프로그램으로 변환하는데 필요한 기능은 아래와 같다.
1️⃣ mnemonic operation codes (기호 명령어) ➝ machine language codes
STL ➝ 14 (hex)2️⃣ symbolic operands ➝ machine addresses
RETADR → 10333️⃣ 변환된 값을 이용해 주소 지정 방식(addressing mode)을 포함한 정해진 형식의 기계어 명령어 구성
4️⃣ 소스 프로그램 내에 지정된 데이터 상수(data constants) ➝ internal machine representations
EOF → 454F46 (ASCII로 E, O, F)5️⃣ 오브젝트 프로그램과 어셈블리 리스트 파일 생성
그러나 1️⃣~5️⃣의 과정을 소스코드 한 줄씩 순차적으로 처리한다면, translating address 과정에서 문제가 발생할 수 있다. 바로 Forward reference (전방 참조) 때문이다.
Forward reference란 프로그램의 앞부분에서 라벨을 사용하지만, 해당 라벨은 프로그래밍 뒷부분에 정의되는 상황이다.
예를 들어,
Line LOC Source Statement Object Code
10 1000 FIRST STL RETADR 141033
...
95 1033 RETADR RESW 1
위에서 RETADR는 Line 10에서 사용되었지만, Line 95에서 정의되어 아직 RETADR의 주소를 알 수 없다.
➡️ Forward reference 문제를 해결하기 위해 대부분의 어셈블러는 소스 프로그램을 두 번 통과시킨다!
→ 이러한 어셈블러를 2-pass Assembler라고 한다.
어셈블리 코드의 한 줄을 읽고 해당 명령문에 주소를 할당한다.
→ 바이트 단위로 주소를 증가시키고, LOCCTR(위치카운터)를 사용한다.
모든 label에 할당된 주소 값을 저장한다.
→ 2단계에서 사용하기 위해 symbol table에 저장한다.
일부 어셈블러 지시어 처리를 수행한다.
→ 상수 선언, 공간 예약 등
→ 예: BYTE, RESW 등의 크기에 따라 주소 할당에 영향을 주는 지시어 처리 포함
알고리즘

begin
첫 번째 입력 줄을 읽는다
if OPCODE가 'START'라면 then
begin
#[OPERAND]를 시작 주소(starting address)로 저장한다
LOCCTR(location counter)를 시작 주소로 초기화한다
해당 줄을 중간(intermediate) 파일에 기록한다
다음 입력 줄을 읽는다
end (if START)
else
LOCCTR을 0으로 초기화한다
▒▒▒
마지막 줄을 중간(intermediate) 파일에 기록한다
(LOCTR - 시작 주소)를 프로그램 길이로 저장한다
end {Pass 1}
▶ #OPERAND는 START 지시어 뒤에 나오는 주소 값 (예: START 1000)
▶ LOCTR은 현재 명령이 메모리에 배치될 주소를 추적하는 위치 카운터

while OPCODE ≠ 'END' do
begin
if 이 줄이 주석이 아닌 경우 then
begin
만약 LABEL 필드에 심볼이 있다면
begin
SYMTAB에서 LABEL을 검색한다
if 이미 존재한다면
→ 에러 플래그 설정 (중복 심볼)
else
→ (LABEL, LOCTR) 쌍을 SYMTAB에 삽입
end (if symbol)
OPTAB에서 OPCODE를 검색한다
if 찾았다면
→ LOCCTR에 명령어 길이(보통 3)를 더한다
else if OPCODE = 'WORD' then
→ LOCCTR에 3 더하기
else if OPCODE = 'RESW' then
→ LOCCTR에 3 * #[OPERAND] 더하기
else if OPCODE = 'RESB' then
→ LOCCTR에 #[OPERAND] 더하기
else if OPCODE = 'BYTE' then
begin
상수의 바이트 길이 계산
LOCCTR에 해당 길이만큼 더하기
end (BYTE)
else
→ 에러 플래그 설정 (유효하지 않은 OPCODE)
end (if not a comment)
중간 파일에 현재 줄을 기록
다음 입력 줄을 읽음
end
end (while not END)
➡️ 결과: 각 source statement와 그에 할당된 주소, 에러 표시 등을 포함한 중간 파일(intermediate file)을 생성한다.
한 줄씩 코드를 읽는다.
→ Pass 1에서 생성된 intermediate file을 2단계의 입력으로 사용한다.
opcode을 번역한다.
→ OP Code Table 사용
label을 address로 변환한다.
→ Symbol Table 사용
1단계에서 수행하지 않았던 assembler directive를 처리한다.
알고리즘

begin
중간 파일에서 첫 번째 입력 라인을 읽는다
if OPCODE = 'START' then
begin
리스트 파일에 라인을 기록한다 (write listing line)
다음 입력 라인을 읽는다
end {if START}
객체 프로그램에 헤더 레코드를 작성한다 (write Header record)
첫 번째 텍스트 레코드를 초기화한다 (initialize first Text record)
▒▒▒ [텍스트 레코드 생성 및 명령어 번역 등 핵심 처리 영역] ▒▒▒
마지막 텍스트 레코드를 객체 프로그램에 기록한다
객체 프로그램에 END 레코드를 작성한다
마지막 리스트 라인을 작성한다
end {Pass 2}

begin
if 이 줄이 주석 줄이 아니라면 then
begin
OPCODE가 OPTAB에 있는지 검색
if 발견되면 then
begin
피연산자(OPERAND)에 심볼이 있다면 then
begin
그 심볼이 SYMTAB에 있는지 검색
if 발견되면 then
피연산자의 주소로 해당 심볼의 값을 저장
else
begin
피연산자 주소로 0 저장
에러 플래그 설정 (정의되지 않은 심볼)
end
end (if symbol)
else
피연산자 주소로 0 저장
객체 코드 명령어를 조립 (assemble the object code instruction)
end (if opcode found)
else if OPCODE = 'BYTE' 또는 'WORD' 라면 then
상수를 객체 코드로 변환
if 객체 코드가 현재 텍스트 레코드에 들어갈 수 없다면 then
begin
현재 텍스트 레코드를 객체 프로그램에 기록
새로운 텍스트 레코드 초기화
end
객체 코드를 텍스트 레코드에 추가
end (주석이 아니라면)
리스트 라인 기록
다음 입력 라인 읽기
end (while not END)
➡️ 결과: object program 생성
mnemonic(기호 형태의) op code와 그에 대응하는 machine language 값 저장
→ 보다 복잡한 어셈블러의 경우, 명령어 형식과 길이가 가변적인 경우 이러한 정보도 포함할 수 있다.
Pass 1: mnemonic code 검색, 유효성 검사
Pass 2: assembly code → machine language
보통 Hash Table로 구성
소스 프로그램의 각 label에 대해 name과 value (address) 저장
Pass 1: 각 label이 등장하면 해당 label과 LOCCTR에서의 주소를 SYMTAB에 저장
Pass 2: 명령어의 operand로 등장한 symbol을 SYMTAB에서 검색해 해당 주소로 변환
보통 Hash Table로 구성
→ 빠른 삽입과 검색
