소스코드(hello.c) -> 전처리(preprocess) -> 전처리 후 소스(hello.i) -> Compiler -> Assembly소스(hello.s) -> Assembler -> 오브젝트파일(hello.o) -> Linker -> 실행파일(hello.out) -> Loader -> Memory
어셈블리 language로 작성된 코드를 machine 코드로 변환하는 일을 한다.(.o파일 생성) 이때 object 파일은 instruction과 data, 그리고 memory에 어디에 있는지에 대한 정보를 담고 있다. 어셈블러의 기본적인 역할은 operation code를 거기에 상응하는 machine language equivalent로 변환한다. 또한 assigned machine addresses to symbolic labels used by the programmer
opcode 뿐만 아니라 operand도 변환
그 과정에서 label에 대한 address를 찾아야 하고 symbol table이라고 하는 data structure를 사용한다.
Assembler Directive
Directive가 사용된 것은 실제로 머신코드로 변환되는 부분이 아니다.
Example 1
이 어셈블리 코드가 COPY라는 소스코드 이름을 가지고 있고 시작주소는 1000으로 가정하고 있다. 실질적인 instruction은 line10부터 시작한다.
Program with Object Code
각 line별로 object가 어떻게 변환되는지를 봤다면 결국 이게 하나의 object 파일로 만들어져서 output device에 쓰이고 loader에 의해 메모리에 적재된다.
object program format
Col | 의미 |
---|---|
Col. 1 | H |
Col. 2-7 | Program name |
Col. 8-13 | Starting address of object program(hex) |
Col. 14-19 | Length of object program in bytes(hex) |
Col | 의미 |
---|---|
Col. 1 | T |
Col. 2-7 | Starting address of object code in this record(hex) |
Col. 8-9 | Length of object code in this record in bytes(hex) |
Col. 10-69 | Object code, represented in hex(2 columns per byte of object code) |
Col | 의미 |
---|---|
Col. 1 | E |
Col. 2-7 | Address of first executable instruction in object program(hex) |
Object program corresponding to Example 1
107A : 1000부터 2079에서 05라는 1byte를 더하면 된다.
Pass 1 : Define symbols
symbol 혹은 label을 define하는 작업을 한다. Pass1은 intermediate file에 결과물을 쓴다.
Pass 2 : Assemble instructions & generate object program
실제 instruction에 대한 assemble과정을 진행하고 object file을 만든다.
Operational Code Table(OPTAB)
Symbol Table(SYMTAB)
Register-to-register instruction을 사용한다. Immediate&Indirect addressing을 될 수 있는 한 많이 사용한다. 이를 통해 프로그램 실행 속도를 빠르게 할 수 있다. 성능을 높일 수 있다. Immediate를 할 경우 memory reference하는 시간을 줄이기 때문이다.
Multiprogramming을 할 때 즉, time sharing 기법을 통해 하나 이상의 프로그램을 사용하고 싶을 때 유용한 방식이 될 수 있다. 메모리에 공간이 있을 때 이를 적절히 활용한다. Assembler가 직접 메모리에 로딩하는 역할을 수행(이는 로더의 역할)하지는 않으므로 어려움이 있다.
시작 주소에 따라 실제 symbol의 address값이 달라질 수 있다. 따라서 시작 주소가 달라지면 이를 반영할 수 있어야 하는데 assembler는 어디부터 시작하여 값을 바꿔야 하는지 알지 못한다. 이때 assembler가 할 수 있는 것은 '실제 주소가 들어오면 바뀔 수 있다.'라는 정보를 담으면 된다. 그러면 로더가 수정을 해서 실제 시작주소로부터 떨어진 값을 넣는다.
Col | 의미 |
---|---|
Col. 1 | M |
Col. 2-7 | Starting location of the address field to be modified, relative to the beginning of the program(hex) |
Col. 8-9 | Length of the address field to be modified, in half-bytes(hex) |
특정 컴퓨터 구조와 관계없이 공통적으로 적용 가능한 어셈블러의 특성들이다.
Literals
Constant value를 직접적으로 표현할 수 있는 방법이다. 실제 machine instruction에 직접 표현되는 것은 아니고(immediate addressing) 메모리 location에 constant를 잡고 TA를 disp에 활용하는 부분은 기존과 동일하다.
프로그램의 다른 곳에서 상수를 정의하고 레이블을 붙이는 불편을 덜어준다. 이를 통해 가독성을 높이기 위해 사용되고 더 높이기 위해서는 literal pool(LTORG)을 사용한다.
Symbol Definitions
어셈블러들은 프로그램 directive를 제공하는데 프로그래머가 symbol을 define하고 그 symbol의 value를 지정할 수 있는 directive(EQU(equate))를 제공한다. EQU는 absolute and relative 다 가능
Expression
Operand를 선언하는 곳에 수식을 표현할 수 있다. Assembler가 수식을 결국 계산할 수 있다.
ex) BUFEND EQU * : buffer area 다음에 나오는 next byte address
Program Block
within a single object program unit
Block Name | Block Number | Address | Length |
---|---|---|---|
default | 0 | 0 | 0066 |
CDATA | 1 | 66 | 000B |
CBLKS | 2 | 71 | 1000 |