오늘은 어셈블러에 대해서 알아보겠습니다!!!
Assembler
어셈블러는 어셈블리 코드를 목적코드로 변환하는 것을 의미합니다.
실제로, 저번에 보았던 어셈블리 언어의 예시를 다시 기억해봅시다.
이 어셈블리 언어를 목적코드로 바꾸면 아래와 같은 형태로 변환하게 됩니다.
사실 어셈블러는, 이러한 것을 바꾸는데 아스키 표를 이용합니다. 아마 어떠한 프로그래밍 언어를 공부하더라도 어느정도 들어봤을 친숙한 이름이라고 생각합니다.
저희는 지금 16비트 컴퓨터를 설계하고 있습니다. 따라서, 8비트로 표시되는 아스키값을 총 3개로 사용할 수 있습니다. 왜냐하면 맨 앞의 4비트로는 MRI인지 non-MRI인지를 확인해야하기 때문이죠.
여기서 보면, INC와 같은 opcode는 AC의 값을 increment하는 것이므로, operand가 필요없고 이는 non-MRI 중에서도 register-reference이므로 0111인 7의 값을 갖습니다.
나머지 뒤의 12비트로는 아스키 값 3개를 갖습니다. 저희는 Symbolic address를 3글자로 제한했기 때문에, 이와 같은 것이 가능해집니다. 따라서 저희는 이제, 어셈블리 언어를 목적코드로 바꿀 수 있게 됩니다. 아래는 이렇게 변환하는 과정에 대한 상세 과정을 설명합니다.
그럼 이제, 정말 어셈블리 언어를 어셈블러가 목적코드로 바꾸기 위해 실행하는 단계에 대해서 알아봅시다.
어셈블러는 총 2단계의 pass를 통해서 목적코드로 변환합니다.
1st Pass
우선 첫번째 pass에서는 address symbol table이라는 것을 생성합니다. 이는, symbol address에 대한 주소를 생성하는 단계라고도 할 수 있습니다.
자 우선, 간단한 어셈블러 코드에 대한 예시를 통해서 설명해보겠습니다.
PL3라는 symbolic address로 LDA SUB I를 지정했습니다.
자 우리는 16비트 컴퓨터를 만들고 있음을 꼭 염두해둡시다. 우리는 아스키 코드를 통해서 어셈블리어를 16진수로 나타낼 수 있습니다.
우리는 16비트이므로 아스키 코드 2개를 메모리에 한 자리에 넣을 수 있고, 따라서 총 2개의 글자를 넣을 수 있습니다.
우리가 symbolic address를 정의할 때, 3글자와 comma로 구성되어있다고 했으므로 2줄의 compact하게 맞춰집니다.
이후, opcode, operand는 총 3글자이고 공백으로 구분되기에, 마지막에 공백을 넣어주어 compact하게 합니다.
마지막으로 I 뒤에는 return을 넣어 온전하게 합니다.
그렇게 완성된 address symbol table은 아래와 같습니다.
PL3라는 symbolic address 마지막에는 comma가, 각 opcode와 operand 뒤에는 space가, 마지막에는 CR(=return)이 있는 형태로 Binary 표현을 만들 수 있게 되는 것입니다.
이제, 플로우 차트를 볼 것인데 그 전에 알아야할 것이 있습니다. 바로, 1st pass에서의 특징인 LC입니다.
Location Counter라는 뜻이 LC는 각 symbolic address가 어느 메모리 주소에 쓰여야하는지를 의미합니다. 전에 들었떤 예시를 통해 다시 설명해보겠습니다.
LC는 pseudoinstruction중 하나인 ORH에 의해서 초기화될 수 있습니다. 초기에는 0이지만, ORG 100을 통해서 LC가 100이 됩니다. 그 후, symbolic address가 있을 때까지 계속해서 진행합니다. 한 row를 지나칠 때마다 LC에 INR을 진행합니다. 그러다가 symbolic address가 존재하는 row를 만났을 때, 비로소 해당 위치에서 작업을 수행합니다. MIN은 106번지에 있습니다. 따라서 106번지는 83의 값이다. 라는 것을 알려주는 address symbolic table을 만드는 것이죠.
설명이 조금 미비하고 미흡한 것 같아서, 아래의 플로우차트를 통해서 다시 확인해봅시다.
앞서 설명했던 83 - (-23)에 대한 어셈블리 언어를 순서대로 진행해보겠습니다.
1. LC <- 0
LC의 값을 0으로 초기화합니다.
2. scan next line
다음 실행할 문장을 읽습니다.
3. Label 체크
ORG 100은 Label이 없으므로 No입니다.
4. ORG 체크
ORG가 true이므로 해당 100 값을 LC에 load합니다. 따라서 이제, LC는 100의 값을 갖게 됩니다.
5. 이제 100번지의 코드를 읽어옵니다.
6. LDA SUB부터 HLT 까지는 label이 없으므로 아무 동작 없이 LC만 INR해줍니다.
7. 만약 이제 MIN, DEC 83을 만났다면 label이 yes가 되고, 해당 83의 값을 MIN과 함께 address symbol table에 저장하게 됩니다.
이렇게 진행되면서 address symboc table을 만드는 것입니다. 그렇게 만들어진 코드는 아래와 같을 것입니다.
2nd Pass
2번째 과정은 이제 실제로 목적 코드를 만들어내는 곳입니다. 만약 두번째 pass에 왔따면 우리는 4가지 table이 있을 것이고, 모든 symbol은 아래의 4개의 table 중 하나에 존재해야합니.
- Pseudoinstruction table
- MRI table
- non-MRI table
- Address symbol table
또한 두번째 과정에서는 Error를 검출할 수 있습니다.
가령, MRI, non-MRI에 없는 machine code symbol이 나타나거나 하는 경우 말이죠.
아래는 2nd pass에서 하는 과정을 플로우차트로 그린 것인데, 아마 1st pass에서와 유사한 부분이 있고, instruction cycle에서 배운 내용이 혼용되어있으니 자세한 설명은 생략하겠습니다.
오늘은 어셈블리 언어에서 실제 기계가 읽을 수 있는 object code로 변환을 수행하는 어셈블러의 수행 과정에 대해서 알아봤습니다. 다음 글에서는 실제로 이러한 어셈블리 언어를 가지고 어떠한 작업을 하도록 코드를 짜보는 것에 대해서 다뤄보겠습니다. 감사합니다.
'CS > Computer Architecture' 카테고리의 다른 글
[컴퓨터구조] 6-4. Assembly Programs - 2 (0) | 2023.10.09 |
---|---|
[컴퓨터구조] 6-3. Assembly Programs -1 (0) | 2023.10.09 |
[컴퓨터구조] 6-1. Assembly Language (0) | 2023.10.08 |
[컴퓨터구조] 5-6. Complete Computer Description (0) | 2023.10.02 |
[컴퓨터구조] 5-5.3. Instruction Cycle(register-reference, I/O Instruction) (0) | 2023.09.27 |